-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HELP] Example of event listening inside the screen widget #31
Comments
If you're new, maybe I'm introducing you to unnecessary complexity, but it might be good for you to learn some basics. Let's say you want to do a search for the API reactively, using Bloc, and you don't want to use any extra packages for that because you want complete control of what you're doing. Example: import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: Get.key,
onGenerateRoute: Router.generateRoute,
navigatorObservers: [GetObserver(MiddleWare.observer)],
home: First(),
);
}
}
class Router {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return GetRoute(
page: First(),
settings: settings,
);
case '/second':
return GetRoute(
settings: settings, page: Second(), transition: Transition.fade);
case '/third':
return GetRoute(
settings: settings,
page: Third(),
transition: Transition.cupertino);
default:
return GetRoute(
settings: settings,
transition: Transition.fade,
page: Scaffold(
body:
Center(child: Text('No route defined for ${settings.name}')),
));
}
}
}
class First extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.add),
onPressed: () {
Get.snackbar("hi", "i am a modern snackbar");
},
),
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Get.toNamed("/second");
},
),
),
);
}
}
class Second extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.add),
onPressed: () {
Get.snackbar("hi", "i am a modern snackbar");
},
),
title: Text('second Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Get.toNamed("/third");
},
),
),
);
}
}
class Third extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => Get.back(),
child: Icon(Icons.arrow_back),
),
appBar: AppBar(
title: Text("Third Route"),
),
body: StreamBuilder<List<Job>>(
stream: JobBloc().jon,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Job> data = snapshot.data;
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index].company,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
)),
subtitle: Text(data[index].description),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
}),
);
}
}
class MiddleWare {
static observer(Routing routing) {
if (routing.current == "/third") {
print(routing.current);
// Fill your class with data
JobBloc().fetchData();
} else if (routing.previous == "/third") {
JobBloc().dispose();
}
}
}
class JobBloc {
//create private instance
static JobBloc _instance;
// create a factory than give always same instance
factory JobBloc() {
if (_instance == null) _instance = JobBloc._();
return _instance;
}
JobBloc._();
//create a Stream
StreamController<List<Job>> _job = StreamController<List<Job>>.broadcast();
fetchData() async {
// fetch data from api
List<Job> data = await Api.result();
//add result on stream
_job.add(data);
}
// expose the stream
get jon => _job.stream;
dispose() {
//close the stream
_job.close();
//Assign your class to null to reset your instance and have GB clear your class from memory to save resources.
_instance = null;
}
}
class Api {
static Future<List<Job>> result() async {
//fetch data from internet
http.Response response =
await http.get("https://mock-json-service.glitch.me/");
if (response.statusCode == 200) {
// Transform the response string into an object
List jsonResponse = json.decode(response.body);
//Iterate each object in a list and return it
return jsonResponse.map((job) => Job.fromJson(job)).toList();
} else {
// show one snackbar on error case
Get.snackbar("Error", "Your API denied this request");
return [];
}
}
}
// create a Model class. I use https://app.quicktype.io/ to autogenerate it
class Job {
final int id;
final String position;
final String company;
final String description;
Job({this.id, this.position, this.company, this.description});
factory Job.fromJson(Map<String, dynamic> json) {
return Job(
id: json['id'],
position: json['position'],
company: json['company'],
description: json['description'],
);
}
}
Note: We don't need any Stateful widgets. |
Hey @jonataslaw thank you a lot for this, I got caught up with other projects, but I'm trying this now. |
This worked like a charm. Thank you for the input Jonny |
Sorry to be bugging so much... can you tell I'm new to flutter?
I was able to implement the middleware to observer every time a screen gets pushed or popped. But I don't understand how to use that to actually perform something on the screen itself. For instance, I want to refresh data from an API every time a screen is either pushed or popped.
I have this in my Middleware
And I do get the name of the screen when I expect it to appear. But how do I call the method on that screen?
Thank you!
The text was updated successfully, but these errors were encountered: