Karan Mehta
Karan Mehta

Reputation: 1541

How to load UI only if the API response comes in flutter?

How can I call an API before the UI gets created and only load the UI if the API response arrives (in flutter).

Basically, I want to only load the UI if an API response arrives otherwise I want to show an error message. How can I achieve this?

Upvotes: 3

Views: 2394

Answers (2)

Vicky Salunkhe
Vicky Salunkhe

Reputation: 10985

I find this method easy for handling this kind of requirement.

1) Create a variable to check whether data has returned successfully or not. bool _loading = true;

2) Create a variable to handle whether there is an error or not. bool _error = false;

3) on the top layer of your widget tree add code with a condition like

_loading ? CircularProgressIndicator() 
         : _error ? errorWidget()
                  : mainWidgetTree()

in your initState Method call your API and set _loading=true;

if api result is successful then set _loading = false;

if there is an error set _error = true;

and then at end of the API call, call setState() method

Upvotes: 0

OMi Shah
OMi Shah

Reputation: 6186

Use FutureBuilder :

Widget that builds itself based on the latest snapshot of the interaction with a Future.

A complete example:

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

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

// podo class
class ObjectClass {
  String name;

  ObjectClass({this.name});

  ObjectClass.fromJson(Map<String, dynamic> json) {
    name = json['name'];
  }
}

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => new _DemoState();
}

class _DemoState extends State<Demo> {
  Future<List<ObjectClass>> fetchJson() async {
    final response = await http.Client().get('your json url');
    return compute(parseJson, response.body);
  }

// A function that converts a response body into a List<ObjectClass>.
  List<ObjectClass> parseJson(String responseBody) {
    final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
    return parsed
        .map<ObjectClass>((json) => ObjectClass.fromJson(json))
        .toList();
  }

  Widget _bodyBuild({List<ObjectClass> data}) {
    return Container(); // make your ui here and use the 'data' variable
  }

  Widget demoBody() {
    return FutureBuilder<List<ObjectClass>>(
      future: fetchJson(), // api call method here, to fetch json/data
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Container(); // widget to be shown on any error
         } 

        return snapshot.hasData
            ? _bodyBuild(data: snapshot.data)
            : Text("Loading"); // widget to be shown while data is being loaded from api call method
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text("DEMO")), body: demoBody());
  }
}

Upvotes: 3

Related Questions