Issue
I have a Provider of an Auth class. When the app loads, I call an API which returns json with data which I map into the Auth class using a factory method (Auth.fromJson). Once the mapping completes, I wish to notify listeners so that the relevant UI is updated. So it turns I cannot call notifyListeners() from the factory constructor because I get this error:
instance members cannot be accessed from a factory constructor
Why is this so? What workaround can I implement? After the factory maps data I need to be able to notifyListeners somehow.
class Auth with ChangeNotifier {
String token;
String organisationId;
String domain;
String userId;
Auth(
{this.token,
this.organisationId,
this.domain,
this.userId});
factory Auth.fromJson(Map<String, dynamic> json) {
Auth(
token: json['token'],
organisationId: json['organisationId'],
domain: json['domain'],
userId: json['userId'],
);
notifyListeners(); // Error here.
return Auth();
}
}
Solution
- factory methods are much like static methods. The way you can’t access class variables and methods applies to factory too.
- notifyListeners(); is a method of ChangeNotifier class and so you can’t access it through any static method or factory methods.
- You will need an instance of Auth to call notifyListeners();
- Better thing to do is to not to make Auth as ChangeNotifier if you really want to observe the change in Auth then make a ChangeNotifer that holds value of Auth. Following is the code for that.
import 'package:flutter/material.dart';
class Auth{
String token;
String organisationId;
String domain;
String userId;
Auth(
{this.token,
this.organisationId,
this.domain,
this.userId});
factory Auth.fromJson(Map<String, dynamic> json) {
return Auth(
token: json['token'],
organisationId: json['organisationId'],
domain: json['domain'],
userId: json['userId'],
);
}
}
class AuthChangeNotifier with ChangeNotifier {
Auth auth;
onNewAuth(Auth newAuth){
this.auth = newAuth;
notifyListeners();
}
}
- You can also use
ValueNotifier<Auth>
for this use-case and observe it usingValueListenableBuilder<Auth>
Hope it helps, let me know if you have any doubts.
Answered By – Kalpesh Kundanani
Answer Checked By – Clifford M. (FlutterFixes Volunteer)