Home > Back-end >  How to setState JSON in DropDownField?
How to setState JSON in DropDownField?

Time:10-23

// ignore_for_file: prefer_const_constructors, avoid_unnecessary_containers, prefer_const_literals_to_create_immutables, import_of_legacy_library_into_null_safe, non_constant_identifier_names, unused_field, avoid_print

import 'dart:convert';

import 'package:dropdownfield/dropdownfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class FoodWidget extends StatefulWidget {
  const FoodWidget({Key? key}) : super(key: key);

  @override
  _FoodWidgetState createState() => _FoodWidgetState();
}

class _FoodWidgetState extends State<FoodWidget> {
  @override
  void initState() {
    fetchFood();
    super.initState();
  }

  String? food_id;
  List food = [];

  Future<void> fetchFood() async {
    final String response =
        await rootBundle.loadString('assets/list_food.json');
    final data = await json.decode(response);
    print(data);
    setState(() {
      food = data["food"];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(15.0),
      child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            DropDownField(
              onValueChanged: (dynamic value) {
                food_id = value;
              },
              value: food_id,
              required: false,
              labelText: 'Search food',
              items: food,
            ),
          ]),
    );
  }
}

and this is the JSON file. I want to get only names in DropDownField but I can't do it. At the setState function, I really don't know how to put it.

{
    "food": [
        {
            "id": 1,
            "name": "coca-cola",
            "calories": 120
        },
        {
            "id": 2,
            "name": "egg",
            "calories": 80
        },
        {
            "id": 3,
            "name": "rice",
            "calories": 100
        }
    ]
}

I tried to print(data) to test the output. It's all coming out of the domain name, but I want to use that inside. And I really don't know how to do it.

PS. I really will appreciate with answers and suggestions.

CodePudding user response:

you would just need to map the data to get only its name :

  Future<void> fetchFood() async {
    final String response =
        await rootBundle.loadString('assets/list_food.json');
    final data = await json.decode(response);
    print(data);
    setState(() {
       food = data["food"].map((e)=>e['name']).toList();
    });
  }

There after getting the list of foods, you map each item to get only the food name, which is what you need.

As a sidenote

I would recommend that in the future you create a model like :

class Food {
    Food({
        this.id,
        this.name,
        this.calories,
    });

    int id;
    String name;
    int calories;

    factory Food.fromJson(Map<String, dynamic> json) => Food(
        id: json["id"],
        name: json["name"],
        calories: json["calories"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "calories": calories,
    };
}

So you have a strongly typed List<Food> food and you could access parameters in a type safe matter.

CodePudding user response:

You need to Generate Food class

class Food {
  String? id;
  String? name;
  String? calories;
  Food({
    this.id,
    this.name,
    this.calories,
  });

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'calories': calories,
    };
  }

  factory Food.fromMap(Map<String, dynamic> map) {
    return Food(
      id: map['id'],
      name: map['name'],
      calories: map['calories'],
    );
  }

  String toJson() => json.encode(toMap());

  factory Food.fromJson(String source) => Food.fromMap(json.decode(source));
}

Full Code here:

  import 'dart:convert';
  import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';

  class FoodWidget extends StatefulWidget {
   const FoodWidget({Key? key}) : super(key: key);

  @override
_FoodWidgetState createState() => _FoodWidgetState();
 }

class _FoodWidgetState extends State<FoodWidget> {
@override
 void initState() {
   fetchFood();
  super.initState();
 }

 String? food_id;
 Food? selected_food ;
  List<Food> food = [];

 Future<void> fetchFood() async {
  final String response =
    await rootBundle.loadString('assets/list_food.json');
  final data = await json.decode(response) as List;
  print(data);
  setState(() {
  food = data.map((e) => Food.fromJson(e)).toList();
   });
  }

 @override
 Widget build(BuildContext context) {
  return Container(
  padding:const EdgeInsets.all(15.0),
  child: Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        DropdownButton<Food>(
          focusColor: Colors.white,
          value: selected_food,
          //elevation: 5,
          style: const TextStyle(color: Colors.white),
          iconEnabledColor: Colors.black,
          underline: const SizedBox.shrink(),
          items: food.map<DropdownMenuItem<Food>>(
              (Food value) {
            return DropdownMenuItem<Food>(
              value: value,
              child: Text(
                value.name!,
                style: const TextStyle(color: Colors.black),
              ),
            );
          }).toList(),
          hint: const Text(
            "Select Shop Category",
            style: TextStyle(
              color: Colors.black38,
            ),
          ),
          onChanged: (Food? value) {
            setState(() {
              selected_food= value!;
            });
            },
          ),
        ]),
     );
    }
   }

    class Food {
     String? id;
     String? name;
     String? calories;
      Food({
       this.id,
       this.name,
      this.calories,
      });

     Map<String, dynamic> toMap() {
      return {
     'id': id,
        'name': name,
     'calories': calories,
    };
    }

    factory Food.fromMap(Map<String, dynamic> map) {
      return Food(
     id: map['id'],
     name: map['name'],
     calories: map['calories'],
    );
    }

   String toJson() => json.encode(toMap());

   factory Food.fromJson(String source) => 
    Food.fromMap(json.decode(source));
    }
  • Related