Home > Mobile >  Flutter how to json decode with a string and a list
Flutter how to json decode with a string and a list

Time:06-21

I've spent around an hour looking for this solution somewhere online. I'm new to flutter & dart languages but I'm very comfortable with C# and .net. Even tho dart/flutter use C# syntax a lot of the language feels much different than I thought it would.

I have a restful API in .net which returns a json object of String : String and String : [Array of Strings]. I have an object class within flutter where I can deserialize the response. I already done this with a normal response of just List and String without a problem but now I ran into massive problem. I don't have a clue how I can deserialise a Json that looks like this.

As requested

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        centerTitle: true,
        backgroundColor: Colors.blueGrey,
        foregroundColor: Colors.white,
      ),
      drawer: const NavigationDrawer(),
      body: Column(
        children: [
          Center(
            child: Text(templateName),
          ),
          Center(
            child: FutureBuilder<TemplateContentAndArgumentsObject>(
              future: templateContent,
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  return Text(snapshot.data?.TemplateContent ?? "null");
                } else {
                  return CircularProgressIndicator();
                }
              },
            ),
          ),
        ],
      ),
    );

Api Call Code

Future<TemplateContentAndArgumentsObject> getTemplateContent(
    String customerId, String templateName) async {
  var url = Uri.parse(
      'https://localhost:7167/api/v1/Templates/$customerId/$templateName');

  var response = await http.get(url, headers: {
    "Accept": "application/json",
    "Access-Control-Allow-Origin": "*"
  });

  try {
    print(response.body);
    var sm = json.decode(response.body);
    print(sm);
  } catch (ex) {
    print(ex);
  }

  if (response.statusCode == 200) {
    TemplateContentAndArgumentsObject obj =
        TemplateContentAndArgumentsObject.fromJson(json.decode(response.body));
    print(obj.TemplateContent);
    print(obj.TemplateArguments);
    return obj;
  } else {
    print('Request failed with status: ${response.statusCode}');
  }

  return TemplateContentAndArgumentsObject(
      TemplateContent: "", TemplateArguments: new List<String>.empty());
}

Class Object

import 'package:flutter/cupertino.dart';

class TemplateContentAndArgumentsObject {
  String TemplateContent;
  List<String> TemplateArguments;

  TemplateContentAndArgumentsObject({
    required this.TemplateContent,
    required this.TemplateArguments,
  });

  factory TemplateContentAndArgumentsObject.fromJson(
    Map<String, dynamic> json,
  ) =>
      TemplateContentAndArgumentsObject(
        TemplateContent: json["TemplateContent"] as String,
        TemplateArguments: (json["TemplateArguments"] as List<String>),
      );
}

Image of Json

CodePudding user response:

Below is Sample Code for your problem. Please be aware that the code is just created based on your example where your list just contains String objects. In case your list contains more advanced objects, we should model them individually and put into a list. But for the strings you can do something like this:

class TemplateContentAndArgumentsObject {
  String myStringContent;
  List<String> myArrayContent;

  TemplateContentAndArgumentsObject({
    required this.myStringContent,
    required this.myArrayContent,
  });

  factory TemplateContentAndArgumentsObject.fromJson(
    Map<String, dynamic> json,
  ) =>
      TemplateContentAndArgumentsObject(
        myStringContent: json["myStringContent"] as String,
        myArrayContent:
            (json["myArrayContent"] as List<dynamic>).cast<String>(),
      );

  Map<String, Object> toJson() => {
        "stringContnet": myStringContent,
        "arrayCOntnet": myArrayContent,
      };
}

I have changed the fromJson constructor into a factory constructor that just calls the class constructor. By doing so it removes the need for the class variables to be declared late.

CodePudding user response:

Hey you can modify your build method, you need to check condition snapshot.hasData, for more detail see FutureBuilder

 @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(title),
            centerTitle: true,
            backgroundColor: Colors.blueGrey,
            foregroundColor: Colors.white,
          ),
          drawer: const NavigationDrawer(),
          body: Column(
            children: [
              Center(
                child: Text(templateName),
              ),
              Center(
                child: FutureBuilder<TemplateContentAndArgumentsObject>(
                  future: templateContent,
                  builder: (context, snapshot) {
    
                    if (snapshot.hasData) {
                      return Text(snapshot.data?.TemplateContent ?? "");
                    }else if (snapshot.hasError){
                        /// return error widget 
                        return Container();
                       } else {
                      return CircularProgressIndicator();
                    }
                  },
                ),
              ),
            ],
          ),
        );

CodePudding user response:

//map to String

Map<String, dynamic> mapData = { "username":name, "email":email, "phoneNumber":mobileNo, "password":password , "refCode": inviteCode, "countryCode":countryCode, "country": "india" };

json.encode(mapData);

// map to list

List values = List();

mapData.forEach((v) => values.add(v)); print(values);

  • Related