I'm trying to make my app fetch data from API every 5 seconds without refreshing the page every time.
How can I achieve it ?
For whoever is facing this error , I fixed it like this.
Timer? t;
#override
void initState() {
super.initState();
t = new Timer.periodic(timeDelay, (t) => fetchDocuments());
}
#override
void dispose() {
t?.cancel();
super.dispose();
}
This is a simple timer that runs every a HTTP lookup every 5 seconds.
import 'package:http/http.dart' as http;
import "dart:async";
void main() {
var timer = Timer.periodic(const Duration(seconds: 5), (_) async {
var album = await fetchAlbum();
print(album.body);
//Update page with data here
});
}
Future<http.Response> fetchAlbum() {
return http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
}
I have included a basic HTTP lookup from here: https://docs.flutter.dev/cookbook/networking/fetch-data
Without knowing more about your app I can't give anymore information.
Related
You can see the strange behaviour in this video: https://streamable.com/r5ld2y
The InitValue is the correct one, but when I restart the App it first goes to zero, AFTER loading the Screen OR press a button, it loads the shared prefs...
This is my Cubit (Only with the LoadCounter Func):
class DrinkCubit extends Cubit<DrinkState> {
DrinkCubit() : super(DrinkState(drinkValue: 0));
Future<void> loadCounter() async {
final prefs = await SharedPreferences.getInstance();
state.drinkValue = (prefs.getInt('counter') ?? 0);
}
}
And this is my InitFunction in the main window!
#override
void initState() {
super.initState();
Future.delayed(Duration.zero,()
{
BlocProvider.of<DrinkCubit>(context).loadCounter();
});
}
So how do I fix this, that the correct value is directly after starting the app showed
Try this:
getData(){
BlocProvider.of<DrinkCubit>(context).loadCounter();
}
#override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((_) {
getData();
});
super.initState();
}
SchedulerBinding.instance.addPostFrameCallback ensures that code inside run before UI code.
And if it allows me to give you a hint, is better remove SharedPreferences of your Bloc and put in another class.
I am working on a slider in flutter which is focused on rating. I want to add a timer to manage a rating time (i.e if the user rated then he/she can't rate again for an hour. Which means once the function is triggered it won't trigger again for a specific time).
So how is it possible to do that. I have a little knowledge about the Timer class and I don't how exactly it should be done. By doing this we are bounding the user not to rate as many times as user want
A simple implementation using a Timer for the functionality you require is to store a bool and start the timer and toggle the bool value when the user performs the function and on timeout toggle the `bool to false and start the timer again.
Below is an example that uses setState.
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home:TimerExample()));
}
class TimerExample extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return _TimerExampleState();
}
}
class _TimerExampleState extends State<TimerExample> {
// Using a short timer for testing, set a duration
// you can set a any duration you like, For Example:
// Duration(hours: 1) | Duration(minutes: 30)
final _timeoutDuration = Duration(seconds:3);
late Timer _timer;
bool _canVote = true;
#override
void dispose() {
super.dispose();
_timer.cancel();
}
void onTimeout() {
setState(() => _canVote = true);
}
void startTimer() {
setState(() {
_canVote = false;
_timer = Timer(_timeoutDuration, onTimeout);
});
}
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: _canVote ? startTimer : null,
child: Text('Vote')
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
#override
void initState() {
getData();
//calling back the request function for data.
super.initState();
}
getData() async {
var response = await http.get(Uri.parse(
"https://newsapi.org/v2/everything?q=tesla&from=2021-06-19&sortBy=publishedAt&apiKey=aef6cc5fa8bb4554a1d76e614b4b5952"));
var jsonData = jsonDecode(response.body);
//change to json type data
print(jsonData);
}
Here is the error I got when I try to request data from API :
Error Photo
try use
#override
void didChangeDependencies() {
getData();
super.didChangeDependencies();
}
instead of
#override
void initState() {
getData();
//calling back the request function for data.
super.initState();
}
Finally I got it.
I mistyped some unnecessary characters in built-in flutter io.dart file.
And sorry for my mistakes.
I've created an app using flutter and I want to get start a timer when the user navigates to a screen to calculate how long will he stay there.
I want if he has completed three minutes on the screen to print anything.
I don't have any ideas about the timer or how to use it.
please help me regarding achieving that.
thanks all.
You can do something like that.
Timer _timer;
#override
void initState() {
_timer = Timer(Duration(milliseconds: 500), () {
// SOMETHING
});
super.initState();
}
#override
void dispose() {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
super.dispose();
}
Please have a look of this:
import 'dart:async';
main() {
const twentyMillis = const Duration(milliseconds:20);
new Timer(twentyMillis, () => print('hi!'));
}
Also look Timer class link
So I'm using the Sparkline library for flutter to create a line chart and it works when I use a static list Eg. ([0, 10, 20, 20, 30]). But I want to make it so that at every say 10 seconds it would add a value, for now that could be anything but later i want to pull that value from firebase.
I've looked at other examples of people trying to run a function multiple time init state but it isnt working. I know I need to redraw the widget but I don't think I'm doing it right or I'm missing something.
class BikeState extends State<BikeScreen> {
Timer timer;
List<double> speedList = new List();
Sparkline speedChart1 = Sparkline(data: [0],);
void updateChart(Timer timer){
speedChart1 = Sparkline(data: speedList,);
speedList.add(10);
speedChart1 = Sparkline(data: speedList,);
}
#override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 15), updateChart);
}
#override
void dispose() {
timer?.cancel();
super.dispose();
}
All that happens when i run it is that I get the just the graph which has the values passed into it when it was declared and nothing was changed.
Flutter will not repaint or rebuild any widgets for you on its own. In your case you already have a stateful widget, which is the correct way, but you also need to tell flutter that your state has changed. This is done by using the setState method like this:
void updateChart(Timer timer) {
setState(() {
speedChart1 = Sparkline(data: speedList,);
speedList.add(10);
speedChart1 = Sparkline(data: speedList,);
});
}
Additionally, depending on how your build method looks, I think you should remove the Sparkline Widget from your state and have it purely during build like this:
class BikeState extends State<BikeScreen> {
Timer timer;
List<double> speedList = new List();
void updateChart(Timer timer){
setState(() {
speedList.add(10);
});
}
#override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 15), updateChart);
}
#override
void dipose() {
timer?.dipose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Sparkline(data: speedList);
}
}