API request returns empty in mapped class

Asked

Viewed 624 times

1

I have a problem trying to return the answer of a api in my class. When I try to run my list returns null instead of the api data

My class Photo

class Foto {

  final int AlbumId;
  final int Id;
  final String Titulo;
  final String Url;
  final String Thumb;

  Foto({this.AlbumId, this.Id, this.Titulo, this.Url, this.Thumb});

  factory Foto.fromJson(Map<String, dynamic> json){
    return new Foto(
      AlbumId: json["albumId"],
      Id: json["id"],
      Titulo: json["title"],
      Url: json["url"],
      Thumb: json["thumbnailUrl"]
    );
  }

}

My Class of Requisition

import 'package:http/http.dart' as http;
import 'package:meu_app/models/Foto.dart';
import 'dart:convert';

import 'package:meu_app/models/Usuario.dart';

class Http {

  get(String url) async {

    http.Response response = await http.get("https://jsonplaceholder.typicode.com/photos");
    decode(response);
  }

  decode(http.Response response){

    if(response.statusCode == 200){

      var decoded = jsonDecode(response.body);

      List<Foto> fotos = decoded.map<Foto>((fotos){
        return Foto.fromJson(fotos);
      }).toList();

      print(fotos);

      return fotos;

    }

  }

1 answer

3


I made some modifications to your example, follow them:

main.Dart

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {

  List<Foto> _fotos;
  Api _api = Api();

  @override
  void initState() {
    super.initState();
    getFotos();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
          body: Center(
            child: _fotos == null
                ? CircularProgressIndicator()
                : ListView.builder(
                itemCount: _fotos.length,
                itemBuilder: (BuildContext context, int index) {
                  Foto foto = _fotos[index];

                  return ListTile (
                    title: Text("${foto.titulo}"),
                    leading: CircleAvatar(
                      backgroundColor: Colors.blueAccent,
                      backgroundImage: NetworkImage("${foto.url}"),
                    ),
                  );
                }
            ),
          ),
        )
    );
  }

  void getFotos() async {
    _fotos = await _api.get();
    setState(() {});
  }
}

photo.Dart

class Foto {

  final int albumId;
  final int id;
  final String titulo;
  final String url;
  final String thumb;

  Foto({this.albumId, this.id, this.titulo, this.url, this.thumb});

  factory Foto.fromJson(Map<String, dynamic> json){
    return Foto(
        albumId: json["albumId"],
        id: json["id"],
        titulo: json["title"],
        url: json["url"],
        thumb: json["thumbnailUrl"]
    );
  }

}

requisicao.Dart

class Api {

  Future<List<Foto>> get() async {
    http.Response response = await http.get(
        "https://jsonplaceholder.typicode.com/photos");
    return decode(response);
  }

  List<Foto> decode(http.Response response) {
    if (response.statusCode == 200) {
      var decoded = jsonDecode(response.body);

      List<Foto> fotos = decoded.map<Foto>((fotos) {
        return Foto.fromJson(fotos);
      }).toList();

      print(fotos);
      return fotos;
    }
  }

}

Upshot

GIF

Well, your request and Decode have worked correctly, the problem is that you are working with the Future api and async in the wrong way, you are not reporting the return, remember that in an asynchronous method when Dart arrives at the line it contains await, it already returns a result for who called the method. It is necessary to inform then as return a Future, which is nothing more than a promise, saying that at some point in the future this Future will have a concrete value of that request. To learn more.

Some extra points:

  • Do not use variable name starting with uppercase letter, this is not good practice as stated in the documentation:

Class Members, top-level Definitions, variables, Parameters, and named Parameters should capitalize the first Letter of each word except the first word, and use in separators.

  • Do not use the new for creating objects, from version 2 of Dart this keyword became optional, IE, it is a good practice not to use it given that the code gets more 'clean'.

  • Always note the return of your methods with the type returned (instead of Dynamic), this facilitates the life of the compiler and optimizes the detection of possible errors.

  • I advise not to treat the json Code manually unless it is for learning only, otherwise I recommend working with code generation

  • These initial concepts and a complete example much like what you are doing have in this article here (or in that Github).

  • vlw, not only for the answers but also for the touches.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.