Dendimuhmd
Dendimuhmd

Reputation: 73

I tried to integrate API, but result become null

I tried to integrate Api jsonplaceholder but data still null, how to fix it? i got stuck tonight still now, what is mandatory to fetch api? i don't know how it's work

class Model

import 'package:meta/meta.dart';
import 'dart:convert';

class User {
  User({
    required this.userId,
    required this.id,
    required this.title,
    required this.body,
  });

  final int userId;
  final int id;
  final String title;
  final String body;

  factory User.fromRawJson(String str) => User.fromJson(json.decode(str));

  factory User.fromJson(Map<String, dynamic> json) => User(
        userId: json["albumId"],
        id: json["id"],
        title: json["title"],
        body: json["thumbnailUrl"],
      );


}

Api Service

import 'dart:developer';

import '../db/user_model.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class Service {
  static const baseUrl = 'https://jsonplaceholder.typicode.com/photos/1';
  Future<User> getApi() async {
    var response = await http.get(Uri.parse(baseUrl));
    if (response.statusCode == 200) {
      var data = json.decode(response.body) as Map<String, dynamic>;
      return User.fromJson(data);
    } else {
      throw Exception('Gagal fetch');
    }
  }
}

this link api Link

Api Service

Screen View Result

Result

Upvotes: 0

Views: 151

Answers (1)

Obum
Obum

Reputation: 1623

So using setState, you can have this

main.dart

import 'package:flutter/material.dart';

import 'services/api_service.dart';
import 'db/user_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _service = Service();
  User? _user;

  @override
  initState() {
    _service.getApi().then((user) => setState(() => _user = user));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: _user != null ? Text(_user!.body) : const Text('null'),
        ),
      ),
    );
  }
}

or using FutureBuilder, you can have this

main.dart

import 'package:flutter/material.dart';

import 'services/api_service.dart';
import 'db/user_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder<User?>(
          future: Service().getApi(),
          builder: (context, snapshot) {
            return Center(
              child: snapshot.data != null
                  ? Text(snapshot.data!.body)
                  : const Text('null'),
            );
          },
        ),
      ),
    );
  }
}

Update: Based on your comment for lists

part of api_service.dart

class Service {
  static const baseUrl = 'https://jsonplaceholder.typicode.com/photos';
  Future<List<User>> getApi() async {
    var response = await http.get(Uri.parse(baseUrl));
    if (response.statusCode == 200) {
      var data = json.decode(response.body) as List<dynamic>;
      return data.map((d) => User.fromJson(d)).toList();
    } else {
      throw Exception('Gagal fetch');
    }
  }
}

Note that as we are expecting a list, specifying data as List<dynamic> is okay. If you try to be more specific by doing as List<Map<String, dynamic>>, it won't work. Like, dart will fetch the photos but just won't display them.

part of main.dart

body: FutureBuilder<List<User>>(
  future: Service().getApi(),
  builder: (context, snapshot) {
    return snapshot.data != null
        ? ListView.builder(itemBuilder: ((context, index) {
            return Text(snapshot.data![index].body);
          }))
        : const Center(
            child: Text('null'),
          );
  },
)

Used ListView to show that the data where returned.

Upvotes: 2

Related Questions