How to write exception in build of AsyncNotifier from riverpod - flutter

When not connected to the internet, executing the following code will cause a _ClientSocketException.
How should I write the exception handling?
class AsyncTodosNotifier extends AsyncNotifier<List<Todo>> {
Future<List<Todo>> _fetchTodo() async {
final json = await http.get('api/todos'); //** _ClientSocketException Error occurred**
final todos = jsonDecode(json) as List<Map<String, dynamic>>;
return todos.map((todo) => Todo.fromJson(todo)).toList();
}
#override
Future<List<Todo>> build() async {
return _fetchTodo();
}
Using the AsyncNotifier's build() from riverpod, I would like to code exception handling with AsyncValue.guard, but it results in a syntax error.
How should I write it to make it work?
When trying to get json data, if I can't connect to the internet, I want to write exception handling so that it doesn't abort.
Reference:
https://docs-v2.riverpod.dev/docs/providers/notifier_provider
full code:
implementation.
#immutable
class Todo {
const Todo({
required this.id,
required this.description,
required this.completed,
});
factory Todo.fromJson(Map<String, dynamic> map) {
return Todo(
id: map['id'] as String,
description: map['description'] as String,
completed: map['completed'] as bool,
);
}
final String id;
final String description;
final bool completed;
Map<String, dynamic> toJson() => <String, dynamic>{
'id': id,
'description': description,
'completed': completed,
};
}
class AsyncTodosNotifier extends AsyncNotifier<List<Todo>> {
Future<List<Todo>> _fetchTodo() async {
final json = await http.get('api/todos'); //** _ClientSocketException Error occurred**
final todos = jsonDecode(json) as List<Map<String, dynamic>>;
return todos.map((todo) => Todo.fromJson(todo)).toList();
}
#override
Future<List<Todo>> build() async {
return _fetchTodo();
}
Future<void> addTodo(Todo todo) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
await http.post('api/todos', todo.toJson());
return _fetchTodo();
});
}
}
final asyncTodosProvider =
AsyncNotifierProvider<AsyncTodosNotifier, List<Todo>>(() {
return AsyncTodosNotifier();
});

Related

Flutter: problem in fetching data: type 'Null' is not a subtype of type 'String' error

I am trying to fetch google book search api data.
https://www.googleapis.com/books/v1/volumes?q=%EA%B2%BD%EC%A0%9C
I followed this one:
https://docs.flutter.dev/cookbook/networking/fetch-data
My class:
class Book {
final String id;
final String title;
final List<String> authors;
const Book({
required this.id,
required this.title,
required this.authors,
});
factory Book.fromJson(Map json) {
return Book(
id: json['id'],
title: json['title'],
authors: json['author'],
);
}
}
request data:
late Future<List<Book>> futureBooks;
Future<List<Book>> fetchBooks() async {
Uri url = Uri.parse(
'https://www.googleapis.com/books/v1/volumes?q=경제 경영'); //&maxResults=1
final response = await http.get(url);
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
List<dynamic> items = json['items'];
List<Book> books = (items.map((item) {
return Book.fromJson(item);
})).toList();
return books;
} else {
throw Exception('Failed to load Books');
}
}
#override
void initState() {
super.initState();
futureBooks = fetchBooks();
}
I think I have same issue with this.
How to solve the "Type Null is not a subtype of type ..." error?
So I appended [?] for fields.
class Book {
final String? id;
final String? title;
final List<String>? authors;
It still give me null.
my code:
https://github.com/kangsudal/millie/blob/7f1f912c5a0eba0fe09de67c1c729be73b660da1/lib/screens/0_today/tab_widdget/tab_now.dart#L62
how to get data?
because title and author is not inside item object, it inside volumeInfo, so you much change fromJson method of your Book class to
factory Book.fromJson(Map json) {
return Book(
id: json['id'],
title: json['volumeInfo']['title'],
authors: json['volumeInfo']['author'],
);
}

Error fetching API / A value of type 'List<Heroes>' can't be returned from the method 'getHeroes' because has a return type of 'Future<List<String>?>

im new in Dart/Flutter and im struggling with consuming API, here is my file thats inside my model folder:
List<Heroes> heroesFromJson(String str) =>
List<Heroes>.from(json.decode(str).map((x) => Heroes.fromJson(x)));
String heroesToJson(List<Heroes> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Heroes {
Heroes({
required this.id,
required this.name,
required this.localizedName,
required this.primaryAttr,
required this.attackType,
required this.roles,
});
int id;
String name;
String localizedName;
String primaryAttr;
String attackType;
List<String> roles;
factory Heroes.fromJson(Map<String, dynamic> json) => Heroes(
id: json["id"],
name: json["name"],
localizedName: json["localized_name"],
primaryAttr: json["primary_attr"],
attackType: json["attack_type"],
roles: List<String>.from(json["roles"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"localized_name": localizedName,
"primary_attr": primaryAttr,
"attack_type": attackType,
"roles": List<dynamic>.from(roles.map((x) => x)),
};
}
And here is where im getting the error, inside services folder:
class DotaServices {
Future<List<String>?> getHeroes() async {
var client = http.Client();
var url = Uri.parse('https://api.opendota.com/api/heroes');
var response = await client.get(url);
if (response.statusCode == 200) {
var json = response.body;
return heroesFromJson(json);
}
}
}
The error is occuring in that line:
return heroesFromJson(json);
And the message that appears is:
A value of type 'List<Heroes>' can't be returned from the method 'getHeroes' because it has a return type of 'Future<List<String>?>'.
how to solve it? Im struggling real hard on this :/
Your method returns a list of heroes... so... you need to return a list of heroes:
Future<List<String>?> getHeroes() async {
needs to be
Future<List<Heroes>?> getHeroes() async {
heroesFromJson returns a list of heroes so getHeroes has to return a list of heroes:
Future<List<Heroes>?> getHeroes()
Also, your method heroesFromJson returns a List<Heroes> not nullable, but your method getHeroes() return a List<Heroe>? which is nullable.
You either can make your return from heroesFromJson a nullable list List<T>? or your return from getHeroes() a non-nullable list List
Be careful making your List nullable or non-nullable List<Hero>?, not your Hero List<Hero?>
It seems to me that such code should work more reliably.
return Hero.fromJsonList(json as List);
This small example (including function main) was generated with a very small script.
import 'dart:convert';
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final svc = DotaServices();
final heroes = await svc.getHeroes();
print('Heroes: ${heroes.length}');
}
class DotaServices {
Future<List<Hero>> getHeroes() async {
final client = http.Client();
final url = Uri.parse('https://api.opendota.com/api/heroes');
final response = await client.get(url);
if (response.statusCode == 200) {
final source = response.body;
final json = jsonDecode(source);
return Hero.fromJsonList(json as List);
}
throw StateError('Http error: ${response.statusCode}');
}
}
class Hero {
Hero(
{required this.id,
required this.name,
required this.localizedName,
required this.primaryAttr,
required this.attackType,
required this.roles});
factory Hero.fromJson(Map json) {
return Hero(
id: json['id'] as int,
name: json['name'] as String,
localizedName: json['localized_name'] as String,
primaryAttr: json['primary_attr'] as String,
attackType: json['attack_type'] as String,
roles: json['roles'] == null
? []
: (json['roles'] as List).map((e) => e as String).toList(),
);
}
final int id;
final String name;
final String localizedName;
final String primaryAttr;
final String attackType;
final List<String> roles;
static List<Hero> fromJsonList(List json) {
return json.map((e) => Hero.fromJson(e as Map)).toList();
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'localized_name': localizedName,
'primary_attr': primaryAttr,
'attack_type': attackType,
'roles': roles,
};
}
static List<Map<String, dynamic>> toJsonList(List<Hero> list) {
return list.map((e) => e.toJson()).toList();
}
}
Using this codegen script you can generate the models and serializers.
It also generates a working example.
import 'dart:io';
import 'package:object_serializer/json_serializer_generator.dart';
import 'package:yaml/yaml.dart';
void main() {
final classes = loadYaml(_classes) as Map;
final g = JsonSerializerGenerator();
final classesCode = g.generateClasses(classes);
final values = {
'classes': classesCode,
};
var source = g.render(_template, values);
source = g.format(source);
File('bin/stackoverflow.dart').writeAsStringSync(source);
}
const _classes = '''
Hero:
fields:
id: int
name: String
localizedName: {type: String, alias: localized_name}
primaryAttr: {type: String, alias: primary_attr}
attackType: {type: String, alias: attack_type}
roles: List<String>
''';
const _template = r'''
import 'dart:convert';
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final svc = DotaServices();
final heroes = await svc.getHeroes();
print('Heroes: ${heroes.length}');
}
class DotaServices {
Future<List<Hero>> getHeroes() async {
final client = http.Client();
final url = Uri.parse('https://api.opendota.com/api/heroes');
final response = await client.get(url);
if (response.statusCode == 200) {
final source = response.body;
final json = jsonDecode(source);
return Hero.fromJsonList(json as List);
}
throw StateError('Http error: ${response.statusCode}');
}
}
{{classes}}
''';

how to pass the model class and return data in flutter

Model class:
#JsonSerializable()
class EmpVerifyEntity extends Equatable {
#JsonKey(name: "access_token")
final String accessToken;
final EmpVerifyEmployee employee;
const EmpVerifyEntity(this.accessToken, this.employee);
factory EmpVerifyEntity.fromJson(Map<String, dynamic> json) =>
_$EmpVerifyEntityFromJson(json);
Map<String, dynamic> toJson() => _$EmpVerifyEntityToJson(this);
static const empty = EmpVerifyEntity(
'123',
EmpVerifyEmployee(
'1', 'avatar', 'sId', 'empName', 'empId', 'designation', 1));
#override
String toString() {
return jsonEncode(this);
}
#override
// TODO: implement props
List<Object?> get props => [accessToken, employee];
}
#JsonSerializable()
class EmpVerifyEmployee extends Equatable {
#JsonKey(name: "password")
final String password;
final String avatar;
#JsonKey(name: "_id")
final String sId;
#JsonKey(name: "emp_name")
final String empName;
#JsonKey(name: "emp_id")
final String empId;
final String designation;
#JsonKey(name: "__v")
final int iV;
const EmpVerifyEmployee(this.password, this.avatar, this.sId, this.empName,
this.empId, this.designation, this.iV);
factory EmpVerifyEmployee.fromJson(Map<String, dynamic> json) =>
_$EmpVerifyEmployeeFromJson(json);
Map<String, dynamic> toJson() => _$EmpVerifyEmployeeToJson(this);
static const empty = const EmpVerifyEmployee(
'password', 'avatar', 'sId', 'empName', 'empId', 'designation', 1);
#override
String toString() {
return jsonEncode(this);
}
#override
// TODO: implement props
List<Object?> get props =>
[password, avatar, sId, empName, empId, designation, iV];
}
auth repo:
class AuthenticationRepository {
Future<void> logIn({ //login process
required String username,
required String password,
}) async {
print("------------------");
print(username);
var res = await http.post(
Uri.parse("https://cots.com/api/v1/employee/login"),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json'
},
body: jsonEncode({"emp_id": username, "password": password}));
dynamic data = json.decode(res.body);
print(data);
if (data['employee']["is_active"] == true) {
_controller.add(AuthenticationStatus.authenticated);///here it shows authenticated
}
}
User Repo:
class UserRepository {
EmpVerifyEntity? _empVerifyEntity;
UserRepository(this._empVerifyEntity);
Future<EmpVerifyEntity?> getUser() async {
if (_empVerifyEntity != null) {
return _empVerifyEntity;
}
}
}
Auth Bloc:
class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({
required AuthenticationRepository authenticationRepository,
required UserRepository userRepository,
}) : _authenticationRepository = authenticationRepository,
_userRepository = userRepository,
super(const AuthenticationState.unknown()) {
on<AuthenticationStatusChanged>(_onAuthenticationStatusChanged);
on<AuthenticationLogoutRequested>(_onAuthenticationLogoutRequested);
_authenticationStatusSubscription = _authenticationRepository.status.listen(
(status) => add(AuthenticationStatusChanged(status)),
);
}
final AuthenticationRepository _authenticationRepository;
final UserRepository _userRepository;
late StreamSubscription<AuthenticationStatus>
_authenticationStatusSubscription;
#override
Future<void> close() {
_authenticationStatusSubscription.cancel();
_authenticationRepository.dispose();
return super.close();
}
void _onAuthenticationStatusChanged(
AuthenticationStatusChanged event,
Emitter<AuthenticationState> emit,
) async {
switch (event.status) {
case AuthenticationStatus.unauthenticated:
return emit(const AuthenticationState.unauthenticated());
case AuthenticationStatus.authenticated:
final user = await _tryGetUser();
return emit(user != null
? AuthenticationState.authenticated(user)
: AuthenticationState.unauthenticated());
default:
return emit(const AuthenticationState.unknown());
}
}
void _onAuthenticationLogoutRequested(
AuthenticationLogoutRequested event,
Emitter<AuthenticationState> emit,
) {
_authenticationRepository.logOut();
}
Future<EmpVerifyEntity?> _tryGetUser() async {
try {
final user = await _userRepository.getUser();
return user; /////----------------Here I'm getting null as a user
} catch (e) {
print(e);
}
}
}
I can able to do login but can't able to fetch data because it shows null, In login method I should return data so that I can able to fetch. It is authenticated but user data is null, how to pass the return data to userRepo so that I can fetch in authBloc.
-------------------------------------THank you--------------------------

API Response returns null in Flutter

I'm carrying out a basic fetch API request in the code below. The response I'm receiving gives the values for most of the properties except for two which come as null. This has me thinking if it is my code that's causing this issue to occur or something on the backend side which results into this anomaly. As shown below, the fiels that come as null in my VS Code terminal are product_description and restaurant_id. Although these come as null when displayed on the terminal, on Postman it is a different story as the response comes in full. The code and the responses are as follows:
Response on Postman:
{
"status": "success",
"data": [
{
"product_id": 8,
"restaurant_name": "Mocambo",
"restaurant_id": "6", //This is the field in question
"product_name": "Kaju Paneer",
"product_description": "Tasty yummy paneer gravy dish", //And So is this
"product_image": "/public/assets/product/lgml5L03-19-41.jpg",
"product_selling_price": "320"
}
]
}
Response received on Terminal after API Call:
{"status":"success","data":[{"product_id":8,"restaurant_name":"Mocambo","restaurant_id":"6","product_name":"Kaju Paneer","product_description":"Tasty yummy paneer gravy dish","product_image":"\/public\/assets\/product\/lgml5L03-19-41.jpg","product_selling_price":"320"}
When I try printing all the properties this is what I get(You can see above that I still receive data for restaurant_id and product_description)
I/flutter (10235): Provider product_selling_price 320
I/flutter (10235): Provider product_image /public/assets/product/lgml5L03-19-41.jpg
I/flutter (10235): Provider product_name Kaju Paneer
I/flutter (10235): Provider product_id 8
I/flutter (10235): Provider restaurantName Mocambo
I/flutter (10235): Provider Restaurant ID null //Restaurant ID here comes as null
I/flutter (10235): Provider Restaurant Description null //Restaurant Description comes as null
The codes for the Model Class, the class from which the API is called and the widget where it is used are below:
Model Class
import 'package:meta/meta.dart';
import 'dart:convert';
PopularDishes popularDishesFromJson(String str) =>
PopularDishes.fromJson(json.decode(str));
String popularDishesToJson(PopularDishes data) =>
json.encode(data.toJson());
class PopularDishes {
PopularDishes ({
required this.status,
required this.data,
});
String status;
List<Datum> data;
factory PopularDishes .fromJson(Map<String, dynamic> json) =>
PopularRestaurants(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.productId,
required this.restaurantName,
required this.restaurantId,
required this.productName,
required this.productDescription,
required this.productImage,
required this.productSellingPrice,
});
int productId;
String restaurantName;
String restaurantId;
String productName;
String productDescription;
String productImage;
String productSellingPrice;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
productId: json["product_id"],
restaurantName: json["restaurant_name"],
restaurantId: json["restaurant_id"],
productName: json["product_name"],
productDescription: json["product_description"],
productImage: json["product_image"],
productSellingPrice: json["product_selling_price"],
);
Map<String, dynamic> toJson() => {
"product_id": productId,
"restaurant_name": restaurantName,
"restaurant_id": restaurantId,
"product_name": productName,
"product_description": productDescription,
"product_image": productImage,
"product_selling_price": productSellingPrice,
};
}
The class from where the API is called
class PopularDishesProvider with ChangeNotifier {
Map<String, dynamic> _popularDishes = {};
String baseUrl = 'https://achievexsolutions.in/current_work/eatiano/';
Map<String, dynamic> get popularDishes {
return {..._popularDishes};
}
Future<void> fetchData() async {
final url = Uri.parse(baseUrl + 'api/all_products');
final response = await http.get(url);
print(response.body);
PopularDishes popularDishes = popularDishesFromJson(response.body);
_popularDishes = popularDishes.toJson();
// print(_popularDishes);
}
}
The widget
class PopularDishes extends StatefulWidget {
PopularDishesState createState() => PopularDishesState();
}
class PopularDishesState extends State<PopularDishes> {
bool _isLoading = true;
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
Provider.of<PopularDishesProvider>(context).fetchData().then((_) {
setState(() {
_isLoading = false;
});
});
}
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
var textScale = MediaQuery.of(context).textScaleFactor * 1.1;
var subTitleScale = MediaQuery.of(context).textScaleFactor * 1.4;
final provider = Provider.of<PopularDishesProvider>(context).popularDishes;
print(
'Provider product_selling_price ${provider['data'][0]['product_selling_price']}');
print('Provider product_image ${provider['data'][0]['product_image']}');
print('Provider product_name ${provider['data'][0]['product_name']}');
print('Provider product_id ${provider['data'][0]['product_id']}');
print('Provider restaurantName ${provider['data'][0]['restaurant_name']}');
print('Provider Restaurant ID ${provider['data'][0]['restaurant_id']}'); //Returns null here
print(
'Provider Restaurant Description ${provider['data'][0]['product_description']}'); //Returns null here
}
}
Is there anything I can do to fix this or is this a backend issue?
It may happen if some of your restaurant_id contains null value. If you are getting the response of data Try as follows:
provider['data'][0]['restaurant_id']==null?
print("isEmpty") :
print('Provider Restaurant ID ${provider['data'][0]['restaurant_id']}');
Note, I could not check your Model class because you did not provide PopularRestaurants. Also, I may be mistaken but I don't think you should make async-await function calls inside provider. First call fetchData in your StatefulWidget, then save the data in your provider. I also think you're using didChangeDependencies wrong and what you want is initstate.
This works for me:
Model Class generated from https://javiercbk.github.io/json_to_dart/
class PopularDishesModel {
String? status;
List<Data>? data;
PopularDishesModel({this.status, this.data});
PopularDishesModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = status;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int? productId;
String? restaurantName;
String? restaurantId;
String? productName;
String? productDescription;
String? productImage;
String? productSellingPrice;
Data(
{this.productId,
this.restaurantName,
this.restaurantId,
this.productName,
this.productDescription,
this.productImage,
this.productSellingPrice});
Data.fromJson(Map<String, dynamic> json) {
productId = json['product_id'];
restaurantName = json['restaurant_name'];
restaurantId = json['restaurant_id'];
productName = json['product_name'];
productDescription = json['product_description'];
productImage = json['product_image'];
productSellingPrice = json['product_selling_price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['product_id'] = productId;
data['restaurant_name'] = restaurantName;
data['restaurant_id'] = restaurantId;
data['product_name'] = productName;
data['product_description'] = productDescription;
data['product_image'] = productImage;
data['product_selling_price'] = productSellingPrice;
return data;
}
}
This is my stateful widget
class PopularDishes extends StatefulWidget {
PopularDishesState createState() => PopularDishesState();
}
class PopularDishesState extends State<PopularDishes> {
String baseUrl = 'https://achievexsolutions.in/current_work/eatiano/';
//Initialize PopularDishesModel
PopularDishesModel savedModel = PopularDishesModel();
//Make sure all json is downloaded
bool _isLoading = true;
//Remove this function from provider and put in your widget
Future<PopularDishesModel> fetchData() async {
final url = Uri.parse(baseUrl + 'api/all_products');
final response = await http.get(url);
//print(response.body);
PopularDishesModel popularDishes = PopularDishesModel.fromJson(json.decode(response.body));
return popularDishes;
}
//This is an async function f
void GetRestaurantData() async
{
PopularDishesModel result = await fetchData();
setState(() {
savedModel = result;
_isLoading = false;
});
}
#override
void initState() {
super.initState();
GetRestaurantData();
}
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
var textScale = MediaQuery.of(context).textScaleFactor * 1.1;
var subTitleScale = MediaQuery.of(context).textScaleFactor * 1.4;
//Add code to save to provider
if(_isLoading == false) {
print(savedModel.data![0].productId);
print(savedModel.data![0].restaurantName);
print(savedModel.data![0].restaurantId);
print(savedModel.data![0].productName);
print(savedModel.data![0].productDescription);
print(savedModel.data![0].productImage);
print(savedModel.data![0].productSellingPrice);
/*Result
8
Mocambo
6
Kaju Paneer
Tasty yummy paneer gravy dish
/public/assets/product/lgml5L03-19-41.jpg
320*/
}
//Add logic to save to provider
return Container();
}
}

How to write test for construction of a class using Dio?

I have a class which will fetch the imgUrl on first creation in the constructor.
And I need to write a test to make sure that the get method of Dio instance is called.
However, I have trouble that the fetch result returns null instead of Future so that I cannot call then.
The class:
#JsonSerializable()
class DogBreed with ChangeNotifier {
#JsonKey(ignore: true)
final Dio dio;
final String id;
final String bred_for;
final String breed_group;
final String life_span;
final String name;
final String origin;
final String temperament;
final String description;
final Measurement height;
final Measurement weight;
var imgUrl = '';
DogBreed({
this.dio,
this.id,
this.bred_for,
this.breed_group,
this.life_span,
this.name,
this.origin,
this.temperament,
this.description,
this.height,
this.weight,
}) {
dio.get(
'xxxxx,
queryParameters: {
'breed_id': id,
'limit': 1,
},
).then((result) {
final List data = result.data;
if (result.statusCode == 200) {
if (data.isNotEmpty) {
imgUrl = result.data[0]['url'];
} else {
imgUrl = NO_IMAGE_AVAILABLE_URL;
}
notifyListeners();
}
});
}
factory DogBreed.fromJson(Map<String, dynamic> json) =>
_$DogBreedFromJson(json);
}
My test:
class MockDio extends Mock implements Dio {}
void main() {
MockDio mockDio;
setUp(() {
mockDio = MockDio();
});
test(
"fetch the imageUrl on constructor",
() async {
when(mockDio.get(any))
.thenAnswer((_) async => Response(data: 'url', statusCode: 200));
final newBreedProvider = DogBreed(
dio: mockDio,
id: '12',
);
verify(mockDio.get(
'xxxx',
queryParameters: {
'breed_id': 12,
'limit': 1,
},
));
},
);
}
Result when run test:
dart:core Object.noSuchMethod
package:practises/projects/dog_facts/providers/dog_breed.dart 46:7 new DogBreed
test/projects/dog_facts/providers/dog_breed_test.dart 24:32 main.<fn>
NoSuchMethodError: The method 'then' was called on null.
Receiver: null
Tried calling: then<Null>(Closure: (Response<dynamic>) => Null)
Could anyone help me to figure out how to write this test or suggest me a new way of implementing so that I can write a test on this one?
I figured out why, it's my mistake that I need to provide queryParameters for get method in the test. It should be:
when(
mockPdio.get(
any,
queryParameters: anyNamed('queryParameters'),
),
).thenAnswer((_) async => Response(data: 'url', statusCode: 200));
Cheers.