Riverpod: Simple way to ingest REST API - flutter

I'm currently building an app that is ingesting the WordPress REST API to display blog posts. On initial app load, I want to have it pull initial data with a method to then pull more posts via user interaction. I currently have this working, however, my implementation seems complex and there may be a cleaner way to get this working. I based my implementation on this GitHub issue response. Here is what my code looks like:
In main.dart:
final blogRepository = FutureProvider((ref) async {
final posts = await getPosts();
return BlogService(posts);
},
);
final blogProvider = StateNotifierProvider<BlogService, List<BlogPost>>((ref) => throw UnimplementedError(
"Access to a [BlogService] should be provided through a [ProviderScope]."));
In blogservice.dart:
class BlogService extends StateNotifier<List<BlogPost>> {
final List<BlogPost> _posts;
BlogService(this._posts) : super(_posts);
List<BlogPost> get posts => _posts;
Future<void> morePosts(int length) async {
Response response;
var dio = Dio();
response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/?offset=' + length.toString());
var posts = (response.data as List);
state = [...state, ...posts.map((post) => BlogPost.fromJson(post)).toList()];
}
}
Future<List<BlogPost>> getPosts() async {
Response response;
var dio = Dio();
response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
var posts = (response.data as List);
return posts.map((post) => BlogPost.fromJson(post)).toList();
}
I think a better way of doing this would be to use AsyncValue, however, I wasn't able to find any good reference implementations consuming an API using this.

This is an example using AsyncValue - It eliminates the repository
Have your service.dart file like this:
final blogServiceProvider = Provider<BlogService>((ref) => BlogService());
class BlogService {
Future<AsyncValue<List<BlogPost>>> getBlogPost() async {
try {
var dio = Dio();
Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
var posts = (response.data as List);
List<BlogPost> list = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
return AsyncData(list);
} catch (e) {
return AsyncError("Something went wrong");
}
}
}
And your provider like so:
final blogNotifierProvider = StateNotifierProvider<BlogNotifier, AsyncValue<List<BlogPost>>>((ref){
BlogService _service = ref.read(blogServiceProvider);
return BlogNotifier(_service);
});
class BlogNotifier extends StateNotifier<AsyncValue<List<BlogPost>>> {
BlogNotifier(this._service) : super(AsyncLoading()) {
getPosts();
}
final BlogService _service;
void getPosts() async {
state = await _service.getBlogPost();
}
}
Edit: To merge existing posts with new ones, try this:
class BlogService {
List<BlogPost> _posts = [];
Future<AsyncValue<List<BlogPost>>> getBlogPost() async {
try {
var dio = Dio();
Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
var posts = (response.data as List);
List<BlogPost> list = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
_posts = list;
return AsyncData(list);
} catch (e) {
return AsyncError("Something went wrong");
}
}
Future<AsyncValue<List<BlogPost>>> morePosts() async {
try {
var dio = Dio();
Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/?offset=' + length.toString());
var posts = (response.data as List);
List<BlogPost> list = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
_posts.addAll(list);
return AsyncData(_posts);
} catch (e) {
return AsyncError("Something went wrong");
}
}
}
And the notifier class would be:
class BlogNotifier extends StateNotifier<AsyncValue<List<BlogPost>>> {
BlogNotifier(this._service) : super(AsyncLoading()) {
getPosts();
}
final BlogService _service;
void getPosts() async {
state = await _service.getBlogPost();
}
void morePosts() async {
state = await _service.morePosts();
}
}

Please best wa create another class to provide data from Api and use drift Package
see my screens how i provide data from database (drift is sqlite DB)
This is my database class based on sqlite(drift)
import 'dart:io';
import 'package:drift/native.dart';
import 'package:mobile_nsk/models/policy/driver.dart';
import 'package:mobile_nsk/models/policy/driver_converter.dart';
import 'package:mobile_nsk/models/policy/holders.dart';
import 'package:mobile_nsk/models/policy/holders_converter.dart';
import 'package:mobile_nsk/models/policy/vehicle.dart';
import 'package:mobile_nsk/models/policy/vehicle_converter.dart';
import 'package:path/path.dart' as p;
import 'package:drift/drift.dart';
import 'package:path_provider/path_provider.dart';
part 'database.g.dart';
LazyDatabase _openConnection()=> LazyDatabase(()async{
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return NativeDatabase(file,logStatements: true);
});
#DriftDatabase(tables: [Holders, Drivers, Vehicles])
class MyDatabase extends _$MyDatabase {
MyDatabase() : super(_openConnection());
// Для страхователя
Future<List<Holder>> getAllHolders() => select(holders).get();
Stream<List<Holder>> watchAllHolder() => select(holders).watch();
Future insertNewHolder(Holder holder) => into(holders).insert(holder, mode: InsertMode.insertOrReplace);
Future deleteHolder(Holder holder) => delete(holders).delete(holder);
Future<Holder> getHolderById(Holder holder)=> select(holders).getSingle();
Future insetData(Holder holder) => into(holders).insert(holder, mode: InsertMode.insertOrReplace);
Future updateHolder(Holder holder, int id, String phone) async
{
await update(holders)..where((tbl) => tbl.id.equals(id))..write(HoldersCompanion(phone: Value(phone)));
await into(holders).insert(holder, mode: InsertMode.insertOrReplace);
}
// Для Водителя
Future<List<Driver>> getAllDriver() => select(drivers).get();
Stream<List<Driver>> watchAllDriver() => select(drivers).watch();
Future insertNewDriver(Driver driver) => into(drivers).insert(driver, mode: InsertMode.insertOrReplace);
Future deleteDriver(Driver driver) => delete(drivers).delete(driver);
// Для транспорта
Future<List<Vehicle>> getAllVehicles() => select(vehicles).get();
Stream<List<Vehicle>> watchAllVehicle() => select(vehicles).watch();
Future insertNewVehicle(Vehicle vehicle) => into(vehicles).insert(vehicle, mode: InsertMode.insertOrReplace);
Future deleteVehicle(Vehicle vehicle) => delete(vehicles).delete(vehicle);
// всегда инкрементить версию схему если что то добавил/убрал/изменил/нахуевертил
#override
int get schemaVersion => 1;
}
this iss my holder model (ang generate by build_runner)
import 'package:drift/drift.dart';
import 'package:json_annotation/json_annotation.dart' as j;
import 'package:mobile_nsk/database/database.dart';
import 'package:mobile_nsk/models/policy/holders_converter.dart';
#UseRowClass(Holder)
class Holders extends Table{
IntColumn get id => integer()();
TextColumn get firstName =>text()();
TextColumn get middleName => text()();
TextColumn get lastName => text()();
TextColumn get legalName => text()();
IntColumn get isIndividual => integer()();
TextColumn get iin => text()();
IntColumn get isResident => integer()();
TextColumn get phone => text()();
TextColumn get email => text()();
TextColumn get address => text()();
IntColumn get documentTypeId => integer()();
TextColumn get documentNumber => text()();
TextColumn get documentIssueDate => text()();
TextColumn get classType => text().named("class")();
TextColumn get birthDate => text()();
BoolColumn get isExperienced => boolean()();
BoolColumn get isPrivileged => boolean()();
TextColumn get holders =>
text().map(const HolderConverter()).nullable()();
#override
Set<Column> get primaryKey=> {id};
}
#j.JsonSerializable()
class Holder implements Insertable<Holder>{
final int id;
final String firstName;
final String middleName;
final String lastName;
final String legalName;
final int isIndividual;
final String iin;
final int isResident;
final String phone;
final String email;
final String address;
final int documentTypeId;
final String documentNumber;
final String documentIssueDate;
#j.JsonKey(name: "class")
final String classType;
final String birthDate;
final bool isExperienced;
final bool isPrivileged;
const Holder(this.id, this.firstName, this.middleName, this.lastName, this.legalName, this.isIndividual, this.iin, this.isResident, this.phone, this.email, this.address, this.documentTypeId, this.documentNumber, this.documentIssueDate, this.classType, this.birthDate, this.isExperienced, this.isPrivileged);
factory Holder.fromJson(Map<String, dynamic>json)=> Holder(
json['id'] as int,
json['firstName'] as String? ?? "",
json['middleName'] as String? ?? "",
json['lastName'] as String? ?? "",
json['legalName'] as String? ?? "",
json['isIndividual'] as int,
json['iin'] as String? ?? "",
json['isResident'] as int? ?? 0,
json['phone'] as String? ?? "",
json['email'] as String? ?? "",
json['address'] as String? ?? "",
json['documentTypeId'] as int? ?? 0,
json['documentNumber'] as String? ?? "",
json['documentIssueDate'] as String? ?? "",
json['class'] as String? ?? "",
json['birthDate'] as String? ?? "",
json['isExperienced'] as bool? ?? false,
json['isPrivileged'] as bool? ?? false,
);
Map<String, dynamic>toJson()=>{
'id': id,
'firstName':firstName,
'middleName': middleName,
'lastName': lastName,
'legalName': legalName,
'isIndividual': isIndividual,
'iin': iin,
'isResident': isResident,
'phone': phone,
'email': email,
'address': address,
'documentTypeId': documentTypeId,
'documentNumber': documentNumber,
'documentIssueDate': documentIssueDate,
'class': classType,
'birthDate': birthDate,
'isExperienced': isExperienced,
'isPrivileged': isPrivileged,
};
#override
Map<String, Expression> toColumns(bool nullToAbsent) {
return HoldersCompanion(
id: Value(id),
firstName: Value(firstName),
middleName: Value(middleName),
lastName: Value(lastName),
legalName: Value(legalName),
isIndividual: Value(isIndividual),
iin: Value(iin),
isResident: Value(isResident),
phone: Value(phone),
email: Value(email),
address: Value(address),
documentTypeId: Value(documentTypeId),
documentNumber: Value(documentNumber),
documentIssueDate: Value(documentIssueDate),
classType: Value(classType),
birthDate: Value(birthDate),
isExperienced: Value(isExperienced),
isPrivileged: Value(isPrivileged)
).toColumns(nullToAbsent);
}
}
this is my code inser from api to database
import 'dart:convert';
import 'dart:developer';
import 'package:http/http.dart' as http;
import 'package:mobile_nsk/database/database.dart';
import 'package:mobile_nsk/models/policy/holders.dart';
class HolderProvider {
String baseUrl = 'http://172.16.3.49:9096/api/v1';
Future<void> getHolder(
String iin,MyDatabase database
) async {
final response = await http.get(
Uri.parse(baseUrl + '/Customer/get_full_client?iin=$iin'),
headers: {'Content-Type': 'application/json'});
if (jsonDecode(response.body)['isExperienced'] != false) {
database.insertNewHolder(Holder.fromJson(jsonDecode(response.body)));
} else {
throw Exception();
}
}
}

Related

flutter search from API Json

Im trying to make a searchbar that fetch data from mysql , but i have a problem that when i call data fetch function it returns
Instance of '_Future<List>'
this is my code
Future<List<Students>> getStudents(String id) async {
var url = 'http://localhost/getStudents.php';
final response = await http.post(Uri.parse(url), body: {
'id':id,
});
var res = jsonDecode(response.body)['fname'] as List;
if (response.statusCode == 200) {
return res.map((std) => Students.fromJson(std)).toList();
}else {
throw Exception('Failed to load shows');
}
}
my class :
class Students{
final int id;
final String fname;
final String sname;
final String tname;
const Students( {
required this.id,
required this.sname,
required this.tname,
required this.fname,
});
factory Students.fromJson(Map<String, dynamic> json) => Students(
id: json['Id'],
sname: json['secname'],
tname:json['thirdname'] ,
fname: json['firstname'],
);
}
getStudents is a future function and you need to await for it:
List<Students> result = await getStudents('');

how to make return of model class into list

i have model called LoginPageModel, but the problem is my api have more than one CODD_VALU and CODD_DESC. and i dont know how to return it as list or an array.
This is my LoginPageModel
class LoginPageModel {
String CODD_VALU;
String CODD_DESC;
LoginPageModel({required this.CODD_VALU, required this.CODD_DESC});
static Future<LoginPageModel> connect(String CODD_VALU) async {
Uri url = Uri.parse("http://deltaprima.rmdoo.com/api/niv/all");
var response = await http.get(
url,
headers: {
"CompanyCode": CODD_VALU,
},
);
var dataJson = jsonDecode(response.body);
return LoginPageModel(
CODD_VALU: dataJson[0]["CODD_VALU"],
CODD_DESC: dataJson[0]["CODD_DESC"],
);
}
}
and this is response of my api (Im using postma)
[
{
"CODD_DESC": "DELTA PRIMA",
"CODD_VALU": "01"
},
{
"CODD_DESC": "SAMPLE",
"CODD_VALU": "02"
}
]
and also this is how i will call return value of LoginPageModel Like this
LoginPageModel.connect(data["CODD_VALU"]).then((value) {
print(value.CODD_DESC);
setState(() {
dataOffice = value.CODD_DESC;
});
}
import 'package:wnetworking/wnetworking.dart';
class Offices {
final String name, value;
/* ---------------------------------------------------------------------------- */
Offices(this.name, this.value);
/* ---------------------------------------------------------------------------- */
#override
String toString() => '$name [$value]';
}
class DeltaPrima {
DeltaPrima._();
/* ---------------------------------------------------------------------------- */
static const _url = 'http://deltaprima.rmdoo.com/api/office/all';
/* ---------------------------------------------------------------------------- */
static Future<List<Offices>?> getOffices(String token) async {
var result = (await HttpReqService.get<List>(_url, headers: {'CompanyCode':token}));
if (result == null) return null;
var list = result
.cast<JMap>()
.map((m) => Offices(m['CODD_DESC']!, m['CODD_VALU']!))
.toList()
;
print('Objects => $list');
return list;
}
}
void main(List<String> args) async {
await DeltaPrima.getOffices('MW');
print('Job done!');
}
Output:
Objects => [DELTA PRIMA [01], SAMPLE [02]]
Job done!
The easiest way is as follows:
You need to use a tool that passes Json to Dart class.
For example from https://app.quicktype.io and the result is:
// To parse this JSON data, do
//
// final loginPageModel = loginPageModelFromJson(jsonString);
import 'dart:convert';
List<LoginPageModel> loginPageModelFromJson(String str) =>
List<LoginPageModel>.from(
json.decode(str).map((x) => LoginPageModel.fromJson(x)));
String loginPageModelToJson(List<LoginPageModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class LoginPageModel {
LoginPageModel({
required this.coddDesc,
required this.coddValu,
});
String coddDesc;
String coddValu;
factory LoginPageModel.fromJson(Map<String, dynamic> json) => LoginPageModel(
coddDesc: json["CODD_DESC"],
coddValu: json["CODD_VALU"],
);
Map<String, dynamic> toJson() => {
"CODD_DESC": coddDesc,
"CODD_VALU": coddValu,
};
}
Update Your Login Page Model Like this.
class LoginPageModel {
String CODD_VALU;
String CODD_DESC;
LoginPageModel({required this.CODD_VALU, required this.CODD_DESC});
factory LoginPageModel.fromJson(Map<String, dynamic> json) => LoginPageModel(
coddDesc: json["CODD_DESC"],
coddValu: json["CODD_VALU"],
);
static Future<List<LoginPageModel>> connect(String CODD_VALU) async {
Uri url = Uri.parse("http://deltaprima.rmdoo.com/api/niv/all");
var response = await http.get(
url,
headers: {
"CompanyCode": CODD_VALU,
},
);
var dataJson = jsonDecode(response.body);
Iterable l = json.decode(response.body);
List<LoginPageModel> listmodel = List<LoginPageModel>.from(l.map((model)=> LoginPageModel.fromJson(model)));
return listmodel;
}
}

How to get Single document from firestore and call the fields in UI in flutter/dart

Here is my attempt
In my Controller I have this
class UserController extends GetxController {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
var _proo;
get prooo => _proo;
Future<Member?> readProfile() async {
_proo = FireStoreHelper().fFetch("users", "user1");
}
}
In my FireStoreHelper I have this
class FireStoreHelper {
fFetch(collection, doc) {
final docMember =
FirebaseFirestore.instance.collection(collection).doc(doc);
var query = docMember.get();
return query;
}
This is my Model
class Member {
final String? username;
//...others
Member({
this.username,
//...others
});
static Member fromJson(Map<String, dynamic> json) => Member(
username: json['username'],
//...others
);
}
Then in my UI I have this
Get.lazyPut(() => UserController().readProfile());
return GetBuilder<UserController>(builder: (userController) {
//.......
Text(userController.prooo.username),
}
Actually what am trying get a username of user1 as seen in the Image below
Please help me, I am new to this.
try this one...
fFetch(collection, doc) async {
final docMember = await
FirebaseFirestore.instance.collection(collection).doc(doc).get();
return docMember;
}
static Future<Member?> readProfile() async {
_proo = await FireStoreHelper().fFetch("users", "user1");
Member member = Member.fromJson(_proo);
return member;
}

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 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.