Giter Site home page Giter Site logo

parsingjson-flutter's Introduction

Parsing complex JSON in Flutter

Gives a detailed explanation of working with simple and complex JSON structures using dart:convert library in Flutter along with a sample project with 6+ examples to experiment with.

Tutorial

Read the Medium article here

Types of JSON structures

  • Simple map
  • Simple structure with arrays
  • Simple nested structures
  • Nested structure with Lists
  • List of maps
  • Complex nested structures
  • Simple structure with Nested Maps [parsed using json_serializable library]
  • Demo for Network Calls with examples for GET, POST methods along with FutureBuilder and .then()

How to work with Network Calls?

Not covered in the article

Let's take this API as an example.

Take a look at post_model.dart for the model class and utility methods. I produced it using this converter tool

GET getAllPosts

//services.dart
Future<List<Post>> getAllPosts() async {
  final response = await http.get(url);
  return allPostsFromJson(response.body);
}
// As a part of your UI widget, e.g body of Scaffold widget
FutureBuilder<List<Post>>(
            future: getAllPosts(),
            builder: (context, snapshot) {
              if(snapshot.hasData)
                return Text('Title from Post JSON : ${snapshot.data[0].title}');
              else
                return CircularProgressIndicator();
            }
        )

GET getPost (to get a particular POST by id)

//services.dart
Future<Post> getPost() async{
  final response = await http.get('$url/1'); // the number is the id of the item being accessed
  return postFromJson(response.body);
}
// As a part of your UI widget, e.g body of Scaffold widget
FutureBuilder<Post>(
            future: getPost(),
            builder: (context, snapshot) {
              if(snapshot.hasData)
                return Text('Title from Post JSON : ${snapshot.data.title}');
              else
                return CircularProgressIndicator();
            }
        )

POST createPost

//services.dart
Future<http.Response> createPost(Post post) async{
  final response = await http.post('$url',
      headers: {
        HttpHeaders.contentTypeHeader: 'application/json'
      },
      body: postToJson(post)
  );

  return response;
}
  //call this function when you want to create a new post
 callAPI(){
    Post post = Post(
      body: 'Testing body body body',
      title: 'Flutter jam6'
    ); // creating a new Post object to send it to API
    
    createPost(post).then((response){
        if(response.statusCode > 200)
          print(response.body);
        else
          print(response.statusCode);
    }).catchError((error){
      print('error : $error');
    });
    
  }

parsingjson-flutter's People

Contributors

poojab26 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parsingjson-flutter's Issues

hello can you help?

i have create this class from the same modal you provided with diffrent data, but having issues

import 'dart:io';
import 'package:flutter/material.dart';
import 'product/products.dart';
import 'package:provider/provider.dart';
import 'utils/auth.dart';
import 'navigation.dart';
import 'package:mosquegiving/utils/api_util.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'product/productdetail.dart';
import 'subscription/plan.dart';
import 'searchresult.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';

void main() {
runApp(ChangeNotifierProvider(
create: (BuildContext context) => AuthProvider(),
child: MyApp(),
));
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
title: 'MY Finance',
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@OverRide
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
var _url = Uri.parse(ApiUtility.Main_Url + '/products');
var nexturl;
double average = 2;
ScrollController _scrollController = new ScrollController();
//determine if all data has been recieved
var loadCompleted = false;
List tempList = [];

var mycontroler = TextEditingController();
@OverRide
void initState() {
super.initState();
readToken();
data = getData(_url);
scrollindecator();
}

late Future<List> data;

void scrollindecator() {
_scrollController.addListener(
() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
print('reach to bottom botton');
if (!loadCompleted) {
setState(() {
data = getData(Uri.parse(nexturl));
});
}
}
},
);
}

Future<List> getData(_url) async {
final response = await http.get(_url, headers: {});
if (response.statusCode == 200) {
// ignore: unused_local_variable
var data3 = json.decode(response.body)['links'];
if (data3['next'] != null) {
nexturl = data3['next'];
} else {
loadCompleted = true;
}
var data =
List<Map<String, dynamic>>.from(json.decode(response.body)['data']);
for (int i = 0; i < data.length; i++) {
tempList.add(Product.fromJson(data[i]));
}
return tempList;
} else {
throw SocketException('Make sure you have an internet connection');
}
}

void dispose() {
super.dispose();
_scrollController.dispose();
mycontroler.dispose();
}

void readToken() async {
await Provider.of(context, listen: false).tryToken();
}

Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
double text = MediaQuery.textScaleFactorOf(context);
return Scaffold(
appBar: AppBar(
title: Text(
'Mosque Giving',
style: TextStyle(color: Color(0XFF1A1A1A)),
),
centerTitle: true,
elevation: 0,
backgroundColor: Color(0xFF50BC90),
),
body: ListView(
controller: _scrollController,
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Giving to your local mosque made easy!',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: text * 16,
),
),
SizedBox(
height: height * 0.03,
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0.0),
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0),
blurRadius: 1.0,
),
],
),
child: TextField(
controller: mycontroler,
decoration: InputDecoration(
icon: Padding(
padding: EdgeInsets.only(left: 12.0),
child: Icon(
Icons.search,
color: Colors.grey,
),
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
),
),
),
SizedBox(width: width * 0.00),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0.0),
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0),
blurRadius: 1.0,
),
],
),
child: SizedBox(
height: height * 0.06,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
primary: Color(0xFF50BC90)),
onPressed: () {
if (mycontroler.text == '') {
final snackBar = SnackBar(
content: Text('Please enter a keyword!'));
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Search(mycontroler.text)),
);
}
},
child: Text('search')),
),
),
],
),
SizedBox(
height: 10.0,
),
Row(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'All Mosque',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
],
),
SizedBox(
height: 10.0,
),
],
),
],
),
),
FutureBuilder<List>(
future: data,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
Product product = snapshot.data![index];
if (index == snapshot.data!.length - 1 &&
!loadCompleted) {
return Center(
child: new Opacity(
opacity: 1.0,
child: new CircularProgressIndicator(),
),
);
} else {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: InkWell(
child: Card(
elevation: 0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0),
blurRadius: 1.0,
),
],
),
// color: Colors.black12,
padding: EdgeInsets.all(2),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
Container(
width: double.infinity,
child: Stack(
children: [
Container(
padding: EdgeInsets.only(top: 1),
width: double.infinity,
// child: Image(
// image: NetworkImage(
// ApiUtility.Assest_Url +
// product.dealimage),
// height: 180,
// fit: BoxFit.fitWidth),
),
],
),
),
Container(
width: double.infinity,
child: Stack(
alignment: Alignment.bottomLeft,
children: [
Container(
// color: Colors.black.withOpacity(0.5),
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
Padding(
padding:
const EdgeInsets.all(
1.0),
child: Text(
product.images[0].title,
style: TextStyle(
fontSize: 15,
fontWeight:
FontWeight.bold,
),
)),
Padding(
padding:
const EdgeInsets.fromLTRB(
0, 8, 0, 8),
child: RichText(
text: TextSpan(
children: [
WidgetSpan(
child: Icon(
Icons.location_on,
size: 18,
color: Color(
0xFF50BC90)),
),
TextSpan(
text:
product.address,
style: TextStyle(
color: Colors
.black)),
],
),
),
),
Row(
children: [
RatingBar.builder(
initialRating: average,
minRating: 0,
direction:
Axis.horizontal,
allowHalfRating: false,
itemCount: 5,
itemPadding:
EdgeInsets.symmetric(
horizontal: 4.0),
itemBuilder:
(context, _) => Icon(
Icons.star,
color:
Color(0xFF50BC90),
),
onRatingUpdate: (rating) {
print(rating);
},
),
],
),
Row(
children: [
Container(
height: 40,
child: ElevatedButton(
style: ElevatedButton
.styleFrom(
primary: Color(
0xFF50BC90)),
onPressed: () {
Navigator.of(context)
.push(
_createRoute(
product
.id));
},
child:
Text('Donate Now'),
),
),
SizedBox(width: 3),
Container(
height: 40,
child: ElevatedButton(
style: ElevatedButton
.styleFrom(
primary: Color(
0xFF50BC90)),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new Productdetails(
prd:
new Product(
id: product
.id,
address:
product.address,
title: product
.title,
category:
product.category,
dealimage:
product.dealimage,
description:
product.description,
slug: product
.slug,
))));
},
child: Text(
'View Details'),
),
),
],
)
],
),
),
],
),
),
],
),
),
),
),
);
}
},
);
} else if (snapshot.hasError) {
return Center(
child: Text(
"Make sure you have an active internet connection"));
}
return Center(child: CircularProgressIndicator());
}),
],
// This trailing comma makes auto-formatting nicer for build methods.
),
drawer: Navigation(),
);
}

Route _createRoute(id) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => Plan(id),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
);
}
}

How to

Hi Pooja,

I am sorry, this is not an issue but a question.
When I implemented your code, I want to pass the value of the Student class to a widget. But it always raised a null error because the data loading hasn't been completed yet (async). Could you give me a clue to handle this problem?

Thanks,

can you please help with parsing this json ?

hi, may i ask you to help me please to parse this json in this url ,

http://opml.radiotime.com/Browse.ashx?render=json&c=podcast

my code is here, so what i did wrong please ?

import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Children>> fetchsprodcasts(http.Client client) async {
  final response =
  await client.get("http://opml.radiotime.com/Browse.ashx?render=json&c=podcast", headers: {'Content-Type': 'application/json; charset=utf-8'});
  return compute(parseProdcasts,utf8.decode(response.bodyBytes));
}
List<Children> parseProdcasts(String responseBody) {
  final parsed = jsonDecode(responseBody)['body'].map((item)=> item['children']).toList().expand((x) => x).toList();
  return parsed.map((m) => new Children.fromJson(m)).toList();
}
class Prodcasts {
  Head head;
  List<Body> body;

  Prodcasts({this.head, this.body});

  Prodcasts.fromJson(Map<String, dynamic> json) {
    head = json['head'] != null ? new Head.fromJson(json['head']) : null;
    if (json['body'] != null) {
      body = new List<Body>();
      json['body'].forEach((v) {
        body.add(new Body.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.head != null) {
      data['head'] = this.head.toJson();
    }
    if (this.body != null) {
      data['body'] = this.body.map((v) => v.toJson()).toList();
    }
    return data;
  }
}
class Head {
  String title;
  String status;

  Head({this.title, this.status});

  Head.fromJson(Map<String, dynamic> json) {
    title = json['title'];
    status = json['status'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['title'] = this.title;
    data['status'] = this.status;
    return data;
  }
}
class Body {
  String element;
  String text;
  List<Children> children;

  Body({this.element, this.text, this.children});

  Body.fromJson(Map<String, dynamic> json) {
    element = json['element'];
    text = json['text'];
    if (json['children'] != null) {
      children = new List<Children>();
      json['children'].forEach((v) {
        children.add(new Children.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['element'] = this.element;
    data['text'] = this.text;
    if (this.children != null) {
      data['children'] = this.children.map((v) => v.toJson()).toList();
    }
    return data;
  }
}
class Children {
  String element;
  String type;
  String text;
  String uRL;
  String guideId;

  Children({this.element, this.type, this.text, this.uRL, this.guideId});

  Children.fromJson(Map<String, dynamic> json) {
    element = json['element'];
    type = json['type'];
    text = json['text'];
    uRL = json['URL'];
    guideId = json['guide_id'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['element'] = this.element;
    data['type'] = this.type;
    data['text'] = this.text;
    data['URL'] = this.uRL;
    data['guide_id'] = this.guideId;
    return data;
  }
}
void main() {
  runApp(ParseProdcastss());
}
class ParseProdcastss extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  ParseProdcasts();
  }
}
class ParseProdcasts extends StatelessWidget {
  ParseProdcasts({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return  FutureBuilder<List<Children>>(
      future: fetchsprodcasts(http.Client()),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);
        return snapshot.hasData
            ? ProdcastsList(childrenList: snapshot.data) :Container(
          color: Colors.white,
              child: Center(child: new CircularProgressIndicator(
          backgroundColor: Color(0xff193451),
          valueColor: AlwaysStoppedAnimation<Color>(Colors.blueGrey),
        )),
            );
      },
    );
  }
}
class ProdcastsList extends StatefulWidget {
  List<Children> childrenList = []; // We assume that you filled this list with children.
  ProdcastsList({Key key, this.childrenList}) : super(key: key);
  @override
  _ProdcastsListState createState() => _ProdcastsListState();
}
class _ProdcastsListState extends State<ProdcastsList> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.blueGrey,
        body: Container(
          color: Colors.blueGrey,
          child: Column(
            children: [
              Expanded(
                child: ListView.builder(
                  physics: ClampingScrollPhysics(),
                  shrinkWrap: true,
                  itemCount: widget.childrenList.length,
                  itemBuilder: (context, index) {
                    return ExpansionTile(
                      backgroundColor: Colors.grey.shade200,
                      children: <Widget>[
                      ],
                      title: Text('${widget.childrenList[index].text}',style: TextStyle(fontSize: 12, color: Colors.blueGrey),),
                      subtitle: Text(''),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

type 'List<dynamic>' is not a subtype of type 'String'

void main() {
  loadPhotos(); // has Unhandled Exception
  runApp(new MyApp());

Report this error:

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'String'
#0      loadPhotos (package:flutter_json/services/photo_services.dart:13:21)
<asynchronous suspension>                                               
#1      main (package:flutter_json/main.dart:12:3)                      
#2      _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
#3      _rootRun (dart:async/zone.dart:1124:13)                         
#4      _CustomZone.run (dart:async/zone.dart:1021:19)                  
#5      _runZoned (dart:async/zone.dart:1516:10)                        
#6      runZoned (dart:async/zone.dart:1500:12)                         
#7      _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)    
#8      _startIsolate.<anonymous closure> (dart:isolate/runtime/lib/isolate_patch.dart:300:19)
#9      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/lib/isolate_patch.dart:171:12)

about translation your article

hi there,
I recently had a trouble to convert JSON in flutter and your article was so helpful for me. so, i want to share your article in Korean so that flutter-starters can get the idea without language barrier. would you mind if I translate your article 'parsing-complex-json in flutter'?

I definately leave your source and original link of the article.

thanks,

When a Json calls an another Json

Hey! Thanks a lot, your article help me so much. But I have a question, not a issue (sorry if I doing this wrong). I'm making an app who based in a WordPress site and the API parse a Json who calls an another Json. So, how I can parsing this? If you wanna to see my code, follow here, have some errors so far, but as long I go coding I will fixing it, or this is the API. Can you help me?

This App will help a lot deaf people in my country!

Thank you again!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.