1

I'm trying to consume an API endpoint with DIO, but it's not showing any data. The endpoint works correctly when I try it with Postman, but I'm not sure what's wrong. Here's my code:

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:tes2/article.dart';

class ArticleProvider extends ChangeNotifier {
  List<Article> articles = [];
  final Dio dio = Dio();

  Future<List<Article>> getAllArticles() async {
    try {
      const String url = 'https://13.210.163.192:8080/users/public/articles';
      Response response = await dio.get(
        url,
      );
      articles = (response.data['data']['article'] as List)
          .map((e) => Article.fromJson(e))
          .toList();

      return articles;
    } catch (e) {
      rethrow;
    }
  }
}

class Article {
  String? id;
  String? image;
  String? title;
  String? author;
  String? topic;
  int? viewCount;
  int? commentCount;
  String? date;
  bool? saved;

  Article({
    this.id,
    this.image,
    this.title,
    this.author,
    this.topic,
    this.viewCount,
    this.commentCount,
    this.date,
    this.saved,
  });

  Article.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    image = json['image'];
    title = json['title'];
    author = json['author'];
    topic = json['topic'];
    viewCount = json['view_count'];
    commentCount = json['comment_count'];
    date = json['date'];
    saved = json['saved'];
  }
}

class ArticleListScreen extends StatelessWidget {
  const ArticleListScreen({Key? key});

  @override
  Widget build(BuildContext context) {
    // Register ArticleProvider as a provider above the widget tree
    final articleProvider = Provider.of<ArticleProvider>(context);

    // Execute fetchArticles when the widget is built
    articleProvider.getAllArticles();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Daftar Artikel'),
      ),
      body: Consumer<ArticleProvider>(
        builder: (context, articleProvider, _) {
          // Check if the article data has been retrieved
          if (articleProvider.articles.isEmpty) {
            return const Center(child: CircularProgressIndicator());
          }

          // Display the article data
          return ListView.builder(
            itemCount: articleProvider.articles.length,
            itemBuilder: (context, index) {
              return ListTile(
                leading:
                    Image.network(articleProvider.articles[index].image ?? ''),
                title: Text(articleProvider.articles[index].title ?? ''),
                subtitle: Text(articleProvider.articles[index].author ?? ''),
              );
            },
          );
        },
      ),
    );
  }
}

Can someone help me? I'm stuck with this error and I've already tried many tutorials but none of them seem to work. The endpoint I'm trying to use is https://13.210.163.192:8080/users/public/articles.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

1 Answers1

0

You need to add notifyListeners();

Add here

  articles = (response.data['data']['article'] as List)
      .map((e) => Article.fromJson(e))
      .toList();
  // This will notify listeners and cause re-render.
  notifyListeners();
  return articles;

But in your current code this may cause recursive calls. so also change the following code

final articleProvider = Provider.of<ArticleProvider>(context);

to

final articleProvider = Provider.of<ArticleProvider>(context,listen: false);

Edit:
I don't know where are you creating the provider. Wherever you are creating it, make sure it's similar to this pattern

  runApp(
    MultiProvider(providers: [
      ChangeNotifierProvider(create: (_)=> ArticleProvider())
    ],
      child: const MyApp(),
    )
  );
Mearaj
  • 1,828
  • 11
  • 14