Try replacing the reference to the instance member with a different expression - flutter

I am using Riverpod to fetch Api and display in the app, and my method , "getMovieList()" requires a String, but in the below code I am getting this Error :
"The instance member 'pageNumber' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expressiondartimplicit_this_reference_in_initializer"
class StateManager {
final String pageNumber;
StateManager(this.pageNumber);
static final movieStateFuture = FutureProvider<List<Movie>>((ref) async {
return ApiSetup.getMovieList(pageNumber); // The error is Here "The instance member 'pageNumber' can't be accessed in an initializer."
});
}
class ApiSetup {
static List<Movie> parsePhotos(String responseBody) {
List<Movie> listMovies = [];
for (var mov in jsonDecode(responseBody)['results']) {
final movie = Movie.fromJson(mov);
listMovies.add(movie);
}
return listMovies;
}
static Future<List<Movie>> getMovieList(String pageNum) async {
final response = await http.get(Uri.parse(
"https://api.themoviedb.org/3/movie/now_playing?api_key=${Constants.apiKey}&language=en-US&page=$pageNum"));
if (response.statusCode == 200) {
return compute(parsePhotos, response.body);
} else {
print("Error here");
}
throw Exception("Some Random Error");
}
}

You can not refer a non static member from inside a static method. Your pageNumber is an attribute that belongs to the instance/object of StateManager whereas static methods belongs to the class.
If you want to use pageNumber while accessing the future try using family provider instead:
static final movieStateFuture = FutureProvider.family<List<Movie>,int>( //<-- Add '.family' modifer and 'datatype' of the argument
(ref, pageNum) async { //<-- Second argument to create method is the parameter you pass
return ApiSetup.getMovieList(pageNum);
}
);
Now while calling movieStateFuture, pass in the argument like this:
watch(movieStateFuture(/*PAGE_NUMBER_HERE*/));

Related

The argument type 'List<HospitalListModel>?' can't be assigned to the parameter type 'HospitalListModel'

i have bloc class and it throw an error with a message The argument type 'List<HospitalListModel>?' can't be assigned to the parameter type 'HospitalListModel'.
this is the bloc class:
class HospitalListBloc extends Bloc<HospitalListEvent, HospitalListState> {
HospitalListBloc() : super(HospitalListInitial()) {
final ApiRepository _apiRepository = ApiRepository();
on<GetCovidList>((event, emit) async {
try {
emit(HospitalListLoading());
final mList = await _apiRepository.fetchHospitalList();
emit(HospitalListLoaded(mList));
} on NetworkError {
emit(HospitalListError("Failed to fetch data. is your device online?"));
}
});
}
}
and the error is on emit(HospitalListLoaded(mList));, and in case if you want to know the API provider:
class ApiProvider {
final Dio _dio = Dio();
final String _url = 'http://lovemonster.my.id/hospital';
Future<List<HospitalListModel>?> fetchHospitalList() async {
try {
Response response = await _dio.get(_url);
return hospitalListModelFromJson(response.data);
} catch (error, stacktrace) {
print("Exception occurred: $error stackTrace: $stacktrace");
return Future.error("");
}
}
}
your HospitalListLoaded function should be
HospitalListLoaded(List<HospitalListModel> mList)
The argument type 'List<HospitalListModel>?' can't be assigned to the parameter type 'HospitalListModel'.
Your HospitalListLoaded function is declared as this:
void HospitalListLoaded(HospitalListModel model){
....
}
Here the parameter type is a single HospitalListModel, not a list of them. So, you can either pass a single HospitalListModel or you can change the parameter type to List<HospitalListModel>. In that case, you must change your logic inside that function.
Plus, notice the ? null operator. If the List you pass can be null, then the parameter type must be nullable. In that case,
void HospitalListLoaded(List<HospitalListModel>? models){
....
}
You are returning an Object of HospitalListModel but your Bloc class having method which accept list of HospitalListModel
You need to return list not an object
Check below code which will be useful
class ApiProvider {
final Dio _dio = Dio();
final String _url = 'http://lovemonster.my.id/hospital';
Future<List<HospitalListModel>?> fetchHospitalList() async {
try {
List<HospitalListModel> hospitalList = [];
Response response = await _dio.get(_url);
var mData = responseData.data as List;
hospitalList = mData.
.map<HospitalListModel?>((e) => hospitalListModelFromJson(e)
.toList();
return hospitalList;//return List not object
} catch (error, stacktrace) {
print("Exception occurred: $error stackTrace: $stacktrace");
return Future.error("");
}
}
}

I can't assign a value to a variable from an asyncron function inside the class

I cannot assign a value to the result variable of type Map<String,dynamic>. I get an error when I define it with late . I think the problem is that I cannot change the value of the variable in the class from within the asyncron function. I couldn't find the reason for this.
I'm so confused. I couldn't find a project or an example that shows how to assign a value to a variable from an asyncron function in any class. You can also suggest a sample project where the http package is used close to the clean code logic. Thank you from now.
void main() {
String urlx = 'http://localhost:8000/process/get_all';
HttpRouter allitem = HttpRouter(url: urlx);
HttpResponser itemyol = HttpResponser();
itemyol.setUrl(urlx);
itemyol.getProcess();
print(itemyol.getItem());
print(itemyol.result);
}
class HttpRouter {
final String url;
HttpRouter({required this.url});
Future<http.Response> getProcess() {
return http.get(Uri.parse(this.url));
}
Future<http.Response> fetchFollowing() {
return http.post(
Uri.parse(this.url),
body: jsonEncode(<String, String>{
'title': "title",
}),
);
}
}
class HttpResponser {
List<dynamic>? result;
late String errorMessage;
late String url;
Future<bool> getProcess() async {
await HttpRouter(url: url).getProcess().then((data) {
if (data.statusCode == 200) {
//There is no problem in this section. The data is coming.
//and I can write with print .
//The problem is that I cannot assign the data to the result variable.
//It always returns null.
setResult(RequestModel.fromJson(json.decode(data.body)).result);
} else {
Map<String, dynamic> result = json.decode(data.body);
setMessage(result['message']);
}
});
return true;
}
setResult(value) {
this.result = value;
}
void setMessage(String value) {
errorMessage = value;
}
List? getItem() {
return this.result;
}
void setUrl(String url) {
this.url = url;
}
}
I tried assigning a value to a variable in a class from an asyncron function in a class, but I couldn't.

Unhandled Exception: type 'Null' is not a subtype of type 'List<dynamic>' in type cast

Objective is to convert a String to List using map and return the value to a function call.
I am using SharedPreferences to save a list of object called where in I save the data at a point and get the data when it is to be put on view.
The below block is the function where the error is occurring.
void getData() async {
final prefs = await SharedPreferences.getInstance();
final String taskString = prefs.getString('task_data').toString();
List<Task> tasksData = Task.decode(taskString);
_tasks = tasksData;
notifyListeners();
}
decode() looks basically does the conversion.
static List<Task> decode(String tasks) {
return (jsonDecode(tasks) as List<dynamic>).map<Task>((task) {
return Task.fromJson(task);
}).toList();
It advises to check for null condition in type cast of decode(). But on performing the check, it gives the same error.
your response might be not a proper map so it cannot decode that data using the jsonDecode function so it returns Null, so you can use your function like this might be helpful for you :
static List<Task> decode(String tasks) {
var data = (jsonDecode(tasks) as List<dynamic>?);
if(data != null){
return (jsonDecode(tasks) as List<dynamic>?)!.map<Task>((task) {
return Task.fromJson(task);
}).toList();
} else {
return <Task>[];
}
}

Exception in json.decode : Closure: () => String from Function 'toString'

I am getting some data from API in flutter. I am trying to decode the data using json.decode() but this decode function gives me the following error:
Closure: () => String from Function 'toString'
Here's my code:
Future<Product> createOrder() async {
var client = new http.Client();
var productModel = null;
try {
var response = await client
.get(Uri.https('butterbasket.onrender.com', Strings.createOrderUrl));
if (response.statusCode == 200) {
var body = response.body;
print("Body: $body");
var jsonMap = json.decode(body);
var productModel = Product.fromJson(jsonMap);
}
} catch (e) {
print("Exception: ${e.toString}");
}
return productModel;
}
Here is the Error Debug Console:
You are running into issues because the data you are loading in is an array, but the model is an object. You'll need to do something like the following:
final List jsonProducts = json.decode(body)
final List<Product> products =
jsonProducts.map((jsonProduct) => Product.fromJson(jsonProduct)).toList();
and then if you only need the first item you can do:
final Product product = products[0]
But don't forget to check if the array is big enough.
Your Future function must return an optional Product?, otherwise your future will never find a result as you are declaring it inside the function.
Instead of:
Future<Product> createOrder() async {}
Use:
Future<Product?> createOrder() async {}
Finally your async snapshot and FutureBuilder type should be of type <Product?>.

flutter return future list in a var to use outside the loop

Hello I'm trying to recuperate the list value of a database.
i can but what i want is to export the result in a var so i can use in all my code just by calling "print(myList);"
this is my code :
static const URL =
'https://xxxhost/employee_actions3.php';
static Future<List<Employee>> getEmployees() async {
try {
final response = await http.post(Uri.parse(
URL,
));
print("getEmployees >> Response:: ${response.body}");
if (response.statusCode == 200) {
List<Employee> list = parsePhotos(response.body);
return list;
} else {
throw <Employee>[];
}
} catch (e) {
return <Employee>[];
}
}
and my classe Employee
class Employee {
String id;
String firstName;
String lastName;
Employee({required this.id, required this.firstName, required this.lastName});
factory Employee.fromJson(Map<String, dynamic> json) {
return Employee(
id: json['id'] as String,
firstName: json['lat'] as String,
lastName: json['lng'] as String,
);
}
}
can i have help please ?
There are two ways to access async data in most modern languages, including dart, they are:
1. By providing a callback then
2. By using the function in an async context and awaiting the result
I've wrapped the code above in a class called API so the examples below are easier to follow,
class API {
static const URL = 'https://xxxhost/employee_actions3.php';
static Future<List<Employee>> getEmployees() async {
try {
final response = await http.post(Uri.parse(URL));
print("getEmployees >> Response:: ${response.body}");
if (response.statusCode == 200) {
List<Employee> list = parsePhotos(response.body);
return list;
} else {
throw("${response.statusCode} Failed to parse photos");
}
} catch (e) {
throw e;
}
}
}
Method 1: Providing a callback to .then, this method will allow you to work with async actions in a synchronous context, but be aware it will not halt the execution flow.
void main() {
API.getEmployees().then((resp) => print(resp)).catchError(e) => print(e);
}
Method 2: Async/Await, this method will allow you to access the data inline, that is var x = await myAsyncFunc() remember the await keyword requires the function to be called within an async context. And the await keyword will halt the execution flow till the future completes.
void main() async {
try {
final list = await API.getEmployees();
print(list);
} catch (e) {
print(e);
}
}
Using either one of the two methods outlined above will allow you to access the data of the list later on.
Additional Reading:
Async programming in dart
Futures and error handling