Since im new to flutter im not able to create a correct data model for my api data.
i got this dummy data at the moment:
List<Product> productsList = [
Product(
id: 1,
title: "Blue Bag",
price: 100,
description: " this is a description",
category: "Clothes",
image: "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",
rating: {rate: 2.1, count: 430}),];
i tried to create a model like this:
class Product {
final int? id;
final String? title;
final double? price;
final String? description;
final String? category;
final String? image;
final double? rate;
final int? count;
final Map<double, int>? rating;
Product({
this.id,
this.title,
this.price,
this.description,
this.category,
this.image,
this.rating,
this.rate,
this.count,
});
}
but the rating is wrong and rating: {rate: 2.1, count: 430} gives me an error.
Im used a little bit in typescript react when i can declare the reating type like
rating: {rate: number, count: number} . How can i do it in flutter?
Related
In Firebase, I have a field called stockBySize, as a map
stockBySize
M: "5"
L: "2"
In flutter app, thats my model:
class Product {
String? id;
String? category;
String? name;
String? description;
String? color;
String? price;
List<String>? images;
Map<String, String>? stockBySize;
factory Product.fromFirestore(
DocumentSnapshot<Map<String, dynamic>> snapshot,
SnapshotOptions? options,
) {
final data = snapshot.data();
return Product(
id: data?['id'],
category: data?['category'],
name: data?['name'],
description: data?['description'],
color: data?['color'],
price: data?['price'],
images: data?['images'] is Iterable ? List.from(data?['images']) : null,
stockBySize: data?['stockBySize'] is Iterable
? Map<String, String>.from(data?['stockBySize'])
: null,
);
}
Below is the code where I read the Firebase data:
Future<List<Product>> findProducts() async {
final query = db.collection("products").withConverter(
fromFirestore: Product.fromFirestore,
toFirestore: (Product product, _) => product.toFirestore(),
);
try {
final docSnap = await query.get();
List<Product> products = [];
docSnap.docs.forEach((element) {
products.add(
Product(
id: element.id,
category: element.data().category,
name: element.data().name,
description: element.data().description,
color: element.data().color,
price: element.data().price,
images: element.data().images,
stockBySize: element.data().stockBySize,
),
);
});
log(products.toString());
return products;
} on FirebaseException {
rethrow;
}
}
The problem: the field stockBySize is always null.
Whats wrong???? The field is written correctly and there is data in firebase
Try the following code:
class Product {
Product({
required this.id,
required this.category,
required this.name,
required this.description,
required this.color,
required this.price,
required this.images,
required this.stockBySize,
});
String? id;
String? category;
String? name;
String? description;
String? color;
String? price;
List<String>? images;
Map<String, dynamic>? stockBySize;
factory Product.fromFirestore(
DocumentSnapshot<Map<String, dynamic>> snapshot,
SnapshotOptions? options,
) {
final data = snapshot.data();
return Product(
id: data?['id'],
category: data?['category'],
name: data?['name'],
description: data?['description'],
color: data?['color'],
price: data?['price'],
images: data?['images'] is Iterable ? List.from(data?['images']) : null,
stockBySize: data?['stockBySize'] is Map<String, dynamic> ? Map<String, dynamic>.from(data?['stockBySize']) : null,
);
}
}
I am facing issue when I am using JsonSerialization on Objectobox Entity
I tried to find better solution but I could not find
#JsonSerializable()
#Entity()
class ContactModel {
#Id()
int internalId;
#Index()
final String? id;
final String? userId;
final String? businessName;
final String? contactPersonName;
final String? contact;
final String? whatsappNumber;
final String? email;
final String? address;
final String? pinCode;
final String? city;
final String? businessType;
final String? description;
final String? img;
final String? lat;
final String? longitude;
final String? createDate;
final String? clientType;
ContactModel(
{this.internalId=0,
this.id,
this.userId,
this.businessName,
this.contactPersonName,
this.contact,
this.whatsappNumber,
this.email,
this.address,
this.city,
this.pinCode,
this.businessType,
this.description,
this.img,
this.lat,
this.longitude,
this.createDate,
this.clientType});
Map<String, dynamic> toMap(ContactModel contactModel) => _$ContactModelToJson(contactModel);
factory ContactModel.fromJson(Map<String, dynamic> json) => _$ContactModelFromJson(json);
}
The data of CategoryModel is storing in allCategory list. I want to store allCategory list locally with hive. How can I do? I tried many attempts but I could not. I also checked questions and answers on stack-overflow and many other websites, I did not get any answer which I wanted. I hope I explained well and you understood.
List<CategoryModel> allCategory =[];
allCategory.add(CategoryModel(/*all variables data*/));
class CategoryModel {
CategoryModel(
{required this.type,
this.iconData,
this.imageList,
this.notesText,
this.reminderIcon,
this.reminderText,
this.reminderTimeText,
this.titel,
this.color,
this.rawList,
this.reminderwidth,
this.backgroundImage,
this.reminderColor,
this.selectedTile,
this.selectedimage,
this.path,
this.crossCount,
this.duration,
this.colorSelected,
this.isSelected = false,
this.checkScreen = false,
this.notesController});
final CategoryType type;
String? titel;
IconData? iconData;
String? notesText;
List<File>? imageList;
IconData? reminderIcon;
String? reminderText;
String? reminderTimeText;
Color? color;
List<ListTileData>? rawList;
double? reminderwidth;
String? backgroundImage;
Color? reminderColor;
int? selectedTile;
int? selectedimage;
bool? checkScreen;
String? notesController;
int? crossCount;
String? path;
Duration? duration;
int? colorSelected;
bool? isSelected;
}
I am writing a bloc test for a feature in my flutter project. I need to code a demo object for a class that I could test in the BlocTest function. Below is a piece of code I wrote for it.
blocTest<ClientBloc, ClientState>(
'emits [ClientLoadSuccess, ClientCreateSuccess] '
'state when successfully created client',
setUp: () {
PrivateClientModel client = { } as PrivateClientModel;
},
build: () => ClientBloc(authenticationBloc: authenticationBloc),
act: (ClientBloc bloc) => bloc.add(
const ClientCreateClient(375918, PrivateClientModel()),
),
expect: () => <dynamic>[
const ClientCreateSuccess(),
],
);
In the above code I need to add an object of PrivateClientModel class whose code lies below. I tried doing some stuff but it did not work so asking here for a good approach.
class PrivateClientModel extends PrivateClientModelParent{
final int id;
final List<TestModel> activeTests;
#JsonKey(name: 'created_at')
final DateTime? createdAt;
final String? businessUid;
final String? uid;
final String? receivingFacility;
final String? firstName;
final String? lastName;
final String? username;
final String? birthDate;
final String? result;
final String? ssnr;
#JsonKey(name: 'insuranceCarrierIdentifier')
final String? insurance;
final String? telephoneNumber;
final String? email;
#JsonKey(name: 'latestPlacerOrderNumber')
final String? placerOrderNumber;
final String? eventNumber;
final String? testIdentifier;
final String? gender;
final String? street;
final String? houseNumber;
final String? zipCode;
final String? city;
#JsonKey(name: 'country_id')
final int? countryId;
final int? redeemable;
#JsonKey(name: 'next_redeemable')
final DateTime? nextRedeemable;
final int? atHome;
#JsonKey(name: 'next_testable')
final DateTime? nextTestable;
final bool isMine;
final bool useAuthUser;
PrivateClientModel(
this.id,
this.activeTests, {
this.createdAt,
this.uid,
this.businessUid,
this.receivingFacility,
this.firstName,
this.lastName,
this.username,
this.birthDate,
this.result,
this.ssnr,
this.insurance,
this.telephoneNumber,
this.email,
this.placerOrderNumber,
this.eventNumber,
this.testIdentifier,
this.gender,
this.street,
this.houseNumber,
this.zipCode,
this.city,
this.countryId,
this.redeemable,
this.nextRedeemable,
this.atHome,
this.nextTestable,
this.isMine = true,
this.useAuthUser = false,
});
factory PrivateClientModel.fromJson(Map<String, dynamic> json) => _$PrivateClientModelFromJson(json);
Map<String, dynamic> toJson() => _$PrivateClientModelToJson(this);
PrivateClientModel copyWith({
int? id,
List<TestModel>? activeTests,
DateTime? createdAt,
String? uid,
String? businessUid,
String? receivingFacility,
String? firstName,
String? lastName,
String? username,
String? birthDate,
String? result,
String? ssnr,
String? insurance,
String? telephoneNumber,
String? email,
String? placerOrderNumber,
String? eventNumber,
String? testIdentifier,
String? gender,
String? street,
String? houseNumber,
String? zipCode,
String? city,
int? countryId,
int? redeemable,
DateTime? nextRedeemable,
int? atHome,
DateTime? nextTestable,
bool? isMine,
bool? useAuthUser,
}) {
return PrivateClientModel(
id ?? this.id,
activeTests ?? this.activeTests,
createdAt: createdAt ?? this.createdAt,
uid: uid ?? this.uid,
businessUid: businessUid ?? this.businessUid,
receivingFacility: receivingFacility ?? this.receivingFacility,
firstName: firstName ?? this.firstName,
lastName: lastName ?? this.lastName,
username: username ?? this.username,
birthDate: birthDate ?? this.birthDate,
result: result ?? this.result,
ssnr: ssnr ?? this.ssnr,
insurance: insurance ?? this.insurance,
telephoneNumber: telephoneNumber ?? this.telephoneNumber,
email: email ?? this.email,
placerOrderNumber: placerOrderNumber ?? this.placerOrderNumber,
eventNumber: eventNumber ?? this.eventNumber,
testIdentifier: testIdentifier ?? this.testIdentifier,
gender: gender ?? this.gender,
street: street ?? this.street,
houseNumber: houseNumber ?? this.houseNumber,
zipCode: zipCode ?? this.zipCode,
city: city ?? this.city,
countryId: countryId ?? this.countryId,
redeemable: redeemable ?? this.redeemable,
nextRedeemable: nextRedeemable ?? this.nextRedeemable,
atHome: atHome ?? this.atHome,
nextTestable: nextTestable ?? this.nextTestable,
isMine: isMine ?? this.isMine,
useAuthUser: useAuthUser ?? this.useAuthUser,
);
}
}
It would be really helpful if someone could help me on how I can create a sample object from this class that I could use in the test.
You can use https://pub.dev/packages/mocktail or https://pub.dev/packages/mockito to create mock objects.
Mockito needs code generation but Mocktail does not.
I want to keep null as a default value for product id, as it'll be later auto-generated, but I can't due to the flutter null safety check.
this is the instance creation code where I want to keep id = null:
var _editedProduct = Product(
id: null,
title: '',
price: 0,
description: '',
imageUrl: '',
);
and here is the code for my Product.dart file:
import 'package:flutter/material.dart';
class Product with ChangeNotifier {
final String id;
final String title;
final String description;
final double price;
final String imageUrl;
bool isFavorite;
Product({
required this.id,
required this.title,
required this.description,
required this.price,
required this.imageUrl,
this.isFavorite = false,
});
void toggleFavoriteStatus() {
isFavorite = !isFavorite;
notifyListeners();
}
}
A screenshot of the error
While you like to have id default value as null, First you need to accept nullable data. For final String id; will be final String? id; the default value can be provided on constructor by removing required to act as optional. id will have null by default.
To use id you need to check if it is null or not.
If you are sure it contains data use ! at the end like id!, or
provide a default value like id??"default", or
if(Product.id!=null){...}
class Product with ChangeNotifier {
final String? id;
final String title;
final String description;
final double price;
final String imageUrl;
bool isFavorite;
Product({
this.id,
required this.title,
required this.description,
required this.price,
required this.imageUrl,
this.isFavorite = false,
});
...
Learn more about null-safety
Following changes solved my issue:
changing final String id; to final String? id; in Product.dart
changing final productId = ModalRoute.of(context)!.settings.arguments as String; to final String? productId = ModalRoute.of(context)!.settings.arguments as String?;