What does " int? get priority => 1;" do? - flutter

I was reading a flutter code as below:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:test_get_app/user_controller.dart';
class AuthMiddleware extends GetMiddleware {
final authService = UserController.findOrInitialize; // Here is error, this line can't find UserController
#override
int? get priority => 1;
bool isAuthenticated = false;
#override
RouteSettings? redirect(String? route) {
isAuthenticated = true;
if (isAuthenticated == false) {
return const RouteSettings(name: '/login');
}
return null;
}
}
When I reached to the following line, I couldn't understand it's syntax and how does it work?
int? get priority => 1;

int? Means it is an int but the int can be null
=> 1 Means () {return 1;}

This is a so-called getter. Getters can be used to provide read access to class properties.
They can also return values directly, like in your case.
They are accessed like properties of the class they are declared in:
final middleWare = AuthMiddleware();
final priority = middleWare.priority;
In your case the getter probably must or can be implemented (see the #override annotation), since all implementations of a middleware must declare their priority, I guess. Since the declared type is int? it may also return null instead of an integer.
Getters can be declared using an expression. Like in your case. Using a block body does also work:
int? get priority {
return 1;
}

Related

Error on generated file for AsyncNotifierProvider `.family` Riverpod providers

I wonder if I am overlooking something. When ever I try to generate the following via riverpod_annotation I'm getting the error below where it cannot find Family class. I'm pretty sure I'm doing something wrong, but I'm not sure what.
I've deleted and rebuilt the file multiple times and I'm not sure what I can change to make it work.
Here's the gist with both the controller and the generated controller logic
https://gist.github.com/Morzaram/7d75bcfed06ea7cce88a8b11c4fad223
import 'package:front_end/utils/pocketbase_provider.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'mangage_topic_voices_controller.g.dart';
#riverpod
class ManageTopicVoicesController extends _$ManageTopicVoicesController {
List<String> _selectedVoices = [];
bool mounted = true;
get selectedVoices => _selectedVoices;
#override
FutureOr<void> build({required List<String> ids}) {
ref.onDispose(() {
mounted = false;
});
if (mounted) {
_selectedVoices = ids;
}
}
void addVoice(String id) {
_selectedVoices = [..._selectedVoices, id];
}
void removeVoice(String id) {
_selectedVoices = _selectedVoices.where((e) => e != id).toList();
}
Future<RecordModel> updateTopic({topicId, selectedVoices}) async {
final res = await pb
.collection('topics')
.update(topicId, body: {"voices": selectedVoices});
return res;
}
}
The error I'm getting is Classes can only extend other classes. Try specifying a different superclass, or removing the extends clause. and it's occuring on the first line of Family<AsyncValue<void>>
class ManageTopicVoicesControllerFamily extends Family<AsyncValue<void>> {
ManageTopicVoicesControllerFamily();
ManageTopicVoicesControllerProvider call({
required List<String> ids,
}) {
return ManageTopicVoicesControllerProvider(
ids: ids,
);
}
#override
AutoDisposeAsyncNotifierProviderImpl<ManageTopicVoicesController, void>
getProviderOverride(
covariant ManageTopicVoicesControllerProvider provider,
) {
return call(
ids: provider.ids,
);
}
#override
List<ProviderOrFamily>? get allTransitiveDependencies => null;
#override
List<ProviderOrFamily>? get dependencies => null;
#override
String? get name => r'manageTopicVoicesControllerProvider';
}
I know that the error is saying that the Family class doesn't exist, but I'm not sure if the error is due to me or not.
Can I not use family with this currently? I would love any help that I can get.
I'm new to dart, so apologies, and thank you in advance!
Here's the gist with both files

How to pass initial value to a Notifier using family modifier?

This is my Notifier:
class Counter extends Notifier<int> {
final int initial;
Counter(this.initial);
#override
int build() => initial;
}
I need to pass initial value to it, but I'm unable to do that using the family modifier anymore.
// Error
final counterProvider = NotifierProvider.family<Counter, int, int>((initial) {
// How to get the initial value to pass here?
return Counter(initial);
});
The syntax for using family/autoDispose using Notifier/AsyncNotifier is different. You're supposed to change the inherited type
So instead of:
final provider = NotifierProvider(MyNotifier.new);
class MyNotifier extends Notifier<Value> {
With family you should do:
final provider = NotifierProvider.family(MyNotifier.new);
class MyNotifier extends FamilyNotifier<Value, Param> {
And the same reasoning applies with autoDispose.

Dart Inherit class and Use it in functions of the parent class

I want to make a parent class which use ChangeNotifier. And from this class, I want to create two separate inherited classes that will provide list data to some parts of the app, and each will have its own separate list. But I could not figure out how each class could create its own list and only make operations on that list via using superclass. Can someone explain to me how can I manage this?
import 'package:flutter/material.dart';
class ObjectListProvider<T extends num, K extends Object> with ChangeNotifier {
final Map<T, K> _map = {};
Map<T, K> get map {
return {..._map};
}
K? getSingleObjectWithId(id) {
return _map[id];
}
void add(T id, K obj) {
_map[id] = obj;
notifyListeners();
}
void remove(T id) {
_map.remove(id);
notifyListeners();
}
}
import 'object_list_provider.dart';
import '../person.dart';
class PersonList extends ObjectListProvider {
final Map<dynamic, Person> _people = {};
}
import './object_list_provider.dart';
import '../group.dart';
import '../person.dart';
class GroupList extends ObjectListProvider {
final Map<dynamic, Group> _groups = {};
void addPersonToGroup<T extends num>(Person person, T id) {
super.add(id, person);
notifyListeners();
}
void removePersonFromGroup<T extends num>(Person person, T id) {
_groups[id]?.removePerson(id);
notifyListeners();
}
}
import './person.dart';
import './transaction.dart';
class Group {
final int _id;
String _name;
List<Person> _people = [];
List<Transaction> _transactions = [];
int _totalSpending;
Group({required int id, required String name, int totalSpending = 0})
: _id = id,
_name = name,
_totalSpending = totalSpending;
int get id {
return _id;
}
String get name {
return _name;
}
int get totalSpending {
return _totalSpending;
}
set name(String newName) {
_name = newName;
}
void addPerson(Person person) {
_people.add(person);
}
void removePerson<T extends num>(T id) {
_people = _people.where((Person person) => person.id != id).toList();
}
void addTransaction(Transaction transaction) {
_transactions.add(transaction);
}
}
class Person {
final int _id;
final String _name;
int _balance;
List<int> involvedGroups = [];
Person({required int id, required String name, int balance = 0})
: _id = id,
_name = name,
_balance = balance;
int get id {
return _id;
}
}
For example, I will use this provider in some other dart file as
final groupList = Provider.of<GroupList>(context);
groupList.add(....)
I refactored my code and came up with a solution that worked for me. Let me try to explain future reads as much as I can.
changed map from private to public. I am not sure it is the best way but it worked for this case. I was also able to work it with getter and setters but by doing that provider object did end up having two variables as _map and map.
import 'package:flutter/material.dart';
class ObjectListProvider<T extends num, K extends Object> with ChangeNotifier {
Map<T, K> map = {};
K? getSingleObjectWithId(id) {
return map[id];
}
void add(T id, K obj) {
map[id] = obj;
notifyListeners();
}
void remove(T id) {
map.remove(id);
notifyListeners();
}
}
Add generics after extending. This way I was able to access the map variable which previously I made publicly accessible. did the same thing for the PersonList as well.
import './object_list_provider.dart';
import '../group.dart';
import '../person.dart';
class GroupList extends ObjectListProvider<num, Group> {
void addPersonToGroup<T extends num>(Person person, T id) {
super.map[id]?.addPerson(person);
notifyListeners();
}
void removePersonFromGroup<T extends num>(Person person, T id) {
super.map[id]?.addPerson(person);
notifyListeners();
}
}
Other than these I did not changed anything related. Now I can call and use provider in some other file as
...
#override
Widget build(BuildContext context) {
final groupList = Provider.of<GroupList>(context);
final groups = groupList.map;
return ListView.builder(
itemCount: groups.length,
itemBuilder: (context, int index) {
return ListTile(
onTap: () => index,
title: Text(groups[groups.keys.elementAt(index)]!.name),
trailing: Text(
groups[groups.keys.elementAt(index)]!.totalSpending.toString(),
),
);
},
);
}
...
I'm working on something simmilar(not current version) at the moment. I would like to try and help if and where I can - though with the caveat that I'm still figuring out a lot of the basics myself.
Could you narrow-down or re-phrase the problem?
What I've done in the app I linked to above, as far as I think it might be relevant to you after a quick skim through your code, what I've done is:
To 'hold' the list and as much as possible of the functionality in the parent class.
In my case, each child class extends that parent - I'm calling it a 'listicle', and the type of object is specific to that childTypeListicle (for now).
The child classes hold specification of the types they list - in my case each it type shares an abstract parent Item class - as well as some config details for e.g. remote access and factory constructors. These' fields communicate up to the parent interfacing and its generic-ized functionality around the list through abstract method declarations enforced by the shared parent class. So that crteates a kind of the list as axel while it its reasonably item-type agnostic. Make sense?
Seems to work well so far, basically holds the logic this side of the plane-of-presentation implementation.
I also have tertiary connected interface elements like bottom-alert-bar connecting into fields of the parent 'listicle', and creating a kind of navigation ui that manipulates the list out onto the listview builder. Would like to also build in some partial local repository-ing but that doesn't seem a priority at the moment for this project.
I hope some of that helps somehow.

Operator can't be unconditionally invoked because the receiver can be null

I'm trying to add shopping functions to my app. I'm attempting to use ChangeNotifier to add a cart item counter and I am getting the error message 'error: The operator '-' can't be unconditionally invoked because the receiver can be 'null'. I'm new to coding so I have been unable to figure out a solution even after researching on SO. Thanks in advance for any help provided.
class EcommerceApp {
static late SharedPreferences sharedPreferences;
static String collectionUser = "users";
static String collectionOrders = "orders";
static String userCartList = 'userCart';
static String subCollectionAddress = 'userAddress';
class CartItemCounter extends ChangeNotifier {
final int _counter = EcommerceApp.sharedPreferences
.getStringList(EcommerceApp.userCartList)
?.length - 1;
int get count => _counter;
}
}
The return value of getStringList() has a chance of being null. Dart's Null-safety doesn't allow this. You can use the ?? operator to ensure another value in case of it being null. I think this might work:
class CartItemCounter extends ChangeNotifier {
final int _counter = (EcommerceApp.sharedPreferences
.getStringList(EcommerceApp.userCartList)
.length ?? 0) - 1;
int get count => _counter;
}

Dart, override many getters and setters in a DRY or synthetic way in a Proxy Pattern

Lets take this dart class:
class Subject {
String a;
String b;
String c;
}
Now I want to use it trough a Proxy, to manage lazy loading and synchronization.
I want as well to have default values to use as placeholders while I'm loading the real data from the net. To keep thighs neat and isolated I added another class:
class Fallback implements Subject {
#override String a = 'a';
#override String b = 'b';
#override String c = 'c';
}
Now I have all the bricks I need to write down the "proxy with fallback" class:
class Proxy implements Subject {
Subject model;
Subject fallback = Fallback();
Future<void> slowlyPopulateModel() async => if (model == null) ... // do some async stuff that valorize model
#override
String get a {
slowlyPopulateModel();
return model?.a ?? fallback.a;
}
#override
set a(String _a) {
model?.a = a;
notifyListener();
}
// same getters and setters for b and c
}
By overriding get a I can call the slow I/O method if needed and return the placeholder value of my Fallback class. Once the new value is set my overridden set a(String _a) will call notifyListener() that will update my interface.
It is working fine, but I have manually override getter and setter for each field of my class (and they are many).
Does Dart have any trick to do this in a more DRY way?
E.g. some way to inject code to be executed before or after each getter or setter?
I would suggest to have a look at Streams for this.
This code example will return an initial value, fetch a new value and notify the listener of it through a stream.
import 'dart:async';
class Subject {
// Current value, initially at "a"
String _a = "a";
StreamController<String> _aController = StreamController<String>();
String get a {
_updateA();
return _a;
}
Stream<String> get aStream => _aController.stream;
void _updateA() async {
String newValue = await _fetchA();
_a = newValue; // update the current value
_aController.add(newValue); // push the new value onto the stream for listeners
}
// return a String after two seconds
Future<String> _fetchA() async {
return Future.delayed(
Duration(seconds: 2),
() => "New value for _a",
);
}
// This closes the stream
void dispose() {
_aController.close();
}
}
main(args) {
final subject = Subject();
// listen to changes
subject.aStream.listen((value) {
print("new value of a: $value");
});
// get current value
final currentValue = subject.a;
print("current value of a: $currentValue");
}
Output of this example
current value of a: a
(after two seconds) new value of a: New value for _a
Use it in Flutter with a StreamBuilder
StreamBuilder<String>(
stream: subject.aStream,
initialData: subject.a,
builder: (context, snapshot) {
final valueOfA = snapshot.data;
return Text("value is $valueOfA");
}
)
Some of the boilerplate code could be replaced by the BehaviorSubject in RxDart. But this would require another dependency to be imported into the project.