0

I'm using a HTTP request that gets a JSON array and pushes this into a JSON object which is read by a list view. I'm having difficulty forcing the JSON array into a JSON object so I'm currently calling each object once via json.decode(response.body)[0]. How can I cast the JSON Array to a JSON Object and have the list view read this entire JSON object?

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<Post> fetchPost() async {
  final url = <my_url>;
  final response =
      await http.get(url);

  if (response.statusCode == 200) {
    // If the call to the server was successful, parse the JSON.
    print(json.decode(response.body));
    // TODO: Identify a way to convert JSON Array to JSON Object
    return Post.fromJson(json.decode(response.body)[0]);
  } else {
    // If that call was not successful, throw an error.
    throw Exception('Failed to load post');
  }
}

class Post {
  final String title;

  Post({this.title});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      title: json['title']
    );
  }
}

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
Future<Post> post;

  @override
  void initState() {
    super.initState();
    post = fetchPost();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Post>(
            future: post,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data.title);
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }

              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}
4
  • Did it show any error? Commented Dec 6, 2019 at 4:20
  • Can you show the json result? Commented Dec 6, 2019 at 4:21
  • can you post your json response? Commented Dec 6, 2019 at 4:39
  • JSON is [{'id': 1, 'title': 'A'}, {'id': 2, 'title': 'B'}. The object is not a Map<String, dynamic> when I remove the index [0] on the response body. I'd like to keep to remove the index and get the entire array into an object Commented Dec 6, 2019 at 6:37

1 Answer 1

4

try this,

Future<List<Post>> fetchPost() async {
  final url = <my_url>;
  final response =
  await http.get(url);

  if (response.statusCode == 200) {
  // If the call to the server was successful, parse the JSON.
  print(json.decode(response.body));
  List<dynamic> responseList =  json.decode(response.body);
  // TODO: Identify a way to convert JSON Array to JSON Object
  List<Post> tempList = [];
  responseList.forEach((f) {
  tempList.add(Post.fromJson(f));
  });
  return tempList;
  } else {
  // If that call was not successful, throw an error.
  throw Exception('Failed to load post');
  }
}

class Post {
  final int id;
  final String title;

  Post({this.id, this.title});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(id: json['id'], title: json['title']);
  }
}

class _Frag_CommitteeState extends State<Frag_Committee> {
  Future<List<Post>> post;

  @override
  void initState() {
    super.initState();
    post = fetchPost();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Fetch Data Example'),
      ),
      body: Center(
        child: FutureBuilder<List<Post>>(
          future: post,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                return Text(snapshot.data[index].title);
              });
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

            // By default, show a loading spinner.
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
} 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This didn't work as is but I was able to hack enough of it to get this to work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.