Comments (3)
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.
At a minimum you need to transform the class Bloc you are going to use into a singleton, so you can access it from anywhere.
The sample code contains a disposable singleton model that replaces the package for example from the provider/get_it. Instead of adding a new dependency, and it will always have the same instance, it will only be placed in memory when you call, and you can give dispose to save memory at any time.
In any other language I prefer DI to use singletons, but in Dart, they are not a problem with tests, and can be disposable, which is a great advantage of using them here.
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.
Every time you leave the screen, your block class will be removed from memory.
If the connection fails, a snackbar will be displayed to alert the user (this is one of the things that is only possible with Get, it would be impossible to call a snackbar of the class API using the default framework).
If you have 10 screens, and you want the data to be updated when the user returns from a screen, this is also possible.
Note2: I am not recommending that you do all your projects like this, it is just an example of possibilities that the Framework gives you, and a way to make your application practically Stateless, which can be advantageous in some projects, but bad in others. If you have a TextEditController, for example, your class must be StatefulWidget, never StatelessWidget.
from getx.
Hey @jonataslaw thank you a lot for this, I got caught up with other projects, but I'm trying this now.
By any chance Is there a place where you hang out to chat about flutter? I wouldn't want to keep making tickets for simple stuff that is outside the scope of the library..
from getx.
This worked like a charm. Thank you for the input Jonny
from getx.
Related Issues (20)
- Instance "GetLifeCycleBase?" is not registered.
- Drawer Menu disappear after changing app locale in drawer
- when I use Get.dialog() to show a dialog, then I use Get.back() back dialog, at the same time ,the page widget's getxController operator onClose(), how to solve this problem. HOT 3
- Get.dilog().adaptive()
- Create a Getx organization HOT 3
- GetX update.
- hello please add material design 3 to this package , thank for persue. HOT 1
- [GETX] "AddWorkerController" deleted from memory but actually not deleted HOT 1
- Displaying a Snackbar that is does not use the full width makes buttons on that height unclickable.
- [Flutter 3.16.5][GetX-5_RC5] PopScope issue HOT 12
- Error: Undefined name 'required'.
- Memory leaks HOT 1
- Can get.to specify context? HOT 1
- RxList in Getx bindStream, but Obx keep get old data emmited
- Nested GetRouterOutlet not working as expected HOT 2
- UI Not Updating with Switch/Toggle in ListView using GetX Controller
- Back button in browser don't behave the same as Get.back()
- Reactive variable observation issues HOT 2
- 是否可以在 GetMiddleware 中拿到正确的 arguments 值
- The GetxController is not automatically deleted if it is the first child of GetMaterialApp HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from getx.