flutterapiriverpod

Flutter riverpod: repeat call API after x second


I am having a problem with riverpod, I need to repeat call API after 5s to get new data from the server and then update the data to the screen. Can you help me? any comments are welcome.

Here my code:

`import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class DataService {
  final Dio _dio = Dio();

  Future<String> getData() async {
    try {
      // For example, I use API https://jsonplaceholder.typicode.com/posts
      Response? response = await _dio.get("https://jsonplaceholder.typicode.com/posts");
      return response.toString();
    } on SocketException {
      throw Exception("SocketException");
    } catch (e) {
      throw Exception(e);
    }
  }
}

 ///////////////////////////////////////////////

final dataService = Provider<DataService>((ref) => DataService());

final dataProvider = FutureProvider<String>((ref) {
  var data = ref.watch(dataService).getData();
  return data;
});

///////////////////////////////////////////////

class MyExampleApp extends ConsumerWidget {
  const MyExampleApp({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    var data = ref.watch(dataProvider);
    //Need to call API after 5s and update new data on the screen

    return MaterialApp(
      home: Scaffold(
        body: Text(data.toString()),
      ),
    );
  }
}

void main() {
  runApp(const ProviderScope(child: MyExampleApp()));
}`

I am still a newbie, hope you help me!


Solution

  • I don't know if it's a good pratice but you can do that.

    final dataProvider = FutureProvider<String>((ref) {
      var data = ref.watch(dataService).getData();
    
      final timer = Timer(const Duration(seconds: 5), (){
        ref.invalidateSelf();
      },);
      ref.onDispose(timer.cancel);
      
      return data;
    });
    

    And you can also use the .when method to display your data

    @override
    Widget build(BuildContext context, WidgetRef ref) {
      var data = ref.watch(dataProvider);
    
      return MaterialApp(
        home: Scaffold(
          body: data.when(
            error: (err, stack) => Text('Error: $err'),
            loading: () => const CircularProgressIndicator(),
            data: (data) => Text(data.toString()),
           ),
         ),
      );
    }