How to Refresh Widget Data

How to refresh Widget data?

You can't use the ObservedObject like you'd normally use in your App.

In Widgets you use a TimelineProvider which creates an Entry for your view.



  1. Add another property to your TimelineEntry, let's call it clubName:
struct SimpleEntry: TimelineEntry {
let date: Date
let clubName: String
}

  1. Update the NetworkManager and return results in the completion:
class NetworkManager {
func fetchData(completion: @escaping ([Post]) -> Void) {
...
URLSession(configuration: .default).dataTask(with: url) { data, _, error in
...
let result = try JSONDecoder().decode(Results.self, from: data)
completion(result.data)
...
}
.resume()
}
}

  1. Use the NetworkManager in the TimelineProvider and create timelines entries when the fetchData completes:
struct Provider: TimelineProvider {
var networkManager = NetworkManager()

func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), clubName: "Club name")
}

func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) {
let entry = SimpleEntry(date: Date(), clubName: "Club name")
completion(entry)
}

func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
networkManager.fetchData { posts in
let entries = [
SimpleEntry(date: Date(), clubName: posts[0].home_name)
]
let timeline = Timeline(entries: entries, policy: .never)
completion(timeline)
}
}
}

  1. Use entry.clubName in the view body:
struct WidgetNeuEntryView: View {
var entry: Provider.Entry

var body: some View {
VStack {
Text(entry.date, style: .time)
Text("Club: \(entry.clubName)")
}
}
}

Note that in the above example the reload policy is set to never to only load the data once.

You can easily change it to atEnd or after(date:) if you want to reload the timeline automatically.

If you need to reload the timeline manually at any point you can just call:

WidgetCenter.shared.reloadAllTimelines()

This will work in both App and Widget.


Here is a GitHub repository with different Widget examples including the Network Widget.

How to refresh Widget when Main App is used?

WidgetCenter.shared.reloadAllTimelines() is independent from the UI framework you use. You can use it from SwiftUI or UIKit.

If you're worried about making too many requests you could call that method only once your app goes to the background.

How do I make my widget update more frequently or update when an action happens within the app

You can always update your widget from your app with the code block below. Please be aware you need to import WidgetKit to your class for calling this function.

WidgetCenter.shared.reloadAllTimelines()

flutter refresh widget's content but it remains old data

use todoFutureBuilder.clear() function

Flutter - How to refresh a Widget on button Click?

I fixed this, I was passing constructor parameters of Portfolio to _PortfolioState, this won't update the values the next time. Instead of passing these values to _PortfolioState, I used widget.coin and widget.days to extract the data from the Portfolio class.

Thanks to this StackOverflow link: Passing Data to a Stateful Widget in Flutter

How can i refresh data immediately after updating it in flutter?

i found the solution i just had to change it in the ui seperatly by changing "quantityData" to an int and increment it in the setstate, this way it keeps updating in the screen

class ProductsInInventoryWidget extends StatefulWidget
{
ProductsInInventory? model;

BuildContext? context;



ProductsInInventoryWidget({this.model,this.context});

@override
_ProductsInInventoryWidgetState createState() => _ProductsInInventoryWidgetState();
}



class _ProductsInInventoryWidgetState extends State<ProductsInInventoryWidget> {



int quantityData =1;




Future addQuantity(int mydata) async
{
String Product_BarCode = widget.model!.productBarcode.toString();
String Inventory_id = widget.model!.inventoryId.toString();
var response = await http.put(
Uri.parse("http://192.168.1.188:8000/api/user/IncrementProduct/$Product_BarCode/$Inventory_id/$mydata",),
body:jsonEncode(<String, String>{
'quantity': mydata.toString(),
}),
);
var body = jsonDecode(response.body);



}


Future<http.Response> DeleteProductFromInventoryProducts(int join_id) async
{
final http.Response response = await http.delete(
Uri.parse("http://192.168.1.188:8000/api/user/deleteProductsFromInventory/$join_id",)
);

return response;


}

@override
void initState() {
// TODO: implement initState
quantityData = widget.model!.quantity; // 2# assign the incoming data here
super.initState();

}


@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top:0.0),
child : Card(

margin: EdgeInsets.fromLTRB(5, 6, 5, 0),
child: Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Column(
children: [
ListTile(
leading: CircleAvatar(
radius:40,
backgroundColor: Colors.black38,
child: Text(quantityData.toString()
,style: TextStyle(
color: Colors.white
),),
),
title: Text(widget.model!.productName), //(widget.model!.ProductName!,),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

Text("code bar : " + widget.model!.productBarcode ),
Text("updated : " + DateFormat('yyyy-MM-dd kk:mm').format(widget.model!.updatedAt)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
icon: Icon(Icons.add,color: Colors.blue,),

onPressed: () async{

// await addQuantity(quantityData);



setState(() {

quantityData+=1;
print(quantityData.toString());
addQuantity(quantityData);
});


}
),
IconButton(
icon: Icon(Icons.remove,color: Colors.blue,),
onPressed: () {
// Perform some action
},

),
FlatButton(
child: const Text('Delete',style: TextStyle(color: Colors.blue),),
onPressed: () {
// Perform some action
setState(() {
// DeleteProductFromInventoryProducts(widget.model!.id.toString());
});
},

),

],
),
],
),
),
],
),
),
)
);
}
}```

iOS 14 Widget auto-refresh every day

Actually, it seems to be I overlooked it, the widget actually refreshes, it was me, who didn't refresh the data itself. (I'm using UserDefaults to share data between my app and the widget, and even though the widget refreshed properly, as the data in UserDefaults was not updated, the same was shown over and over again.)

How to refresh a widget with stream builder in flutter

Every time your widget rebuilds, you get a new stream. This is a mistake. You should obtain the stream only once (for example, in initState)

@override
void initState() {
_stream = quotesdata.fetchdata().asStream();
}

and use that stream variable with StreamBuilder

 StreamBuilder(
stream: _stream,

Later, when you want to update the stream, you can do

setState(() {
_stream = quotesdata.fetchdata().asStream();
})

to change the stream and force a refresh.

Please go over your code and change all such usages

 StreamBuilder(
stream: quotesdata.fetchdata().asStream(),

to this kind of usage.

 StreamBuilder(
stream: _stream,

Otherwise you may get a high backend bill someday. Right now every screen refresh does a new query to the backend.



Related Topics



Leave a reply



Submit