type 'int' is not subtype of type 'String' on Flutter - flutter

I modified description value to 1 on my database.
List<DataEquipmentReg> values = snapshot.data;
assetArray.add('${values[i].eq_no.toString()} : ${values[i].description.toString()}');
After edit description value to String, Error is not coming
DataEquipmentReg POJO Class
class DataEquipmentReg {
final String eq_no;
final String description;
}
Widget
Text(assetArray[index].toString(),),
Database in sqlite
await db.execute("""CREATE TABLE EquipmentRegTable(eq_no STRING, description STRING)""");

I solved this problem like this,
in my read data on cache method, I changed this,
Future<List<DataEquipmentReg>> displayEquipmentReg() async {
var db = await db1;
final List<Map<String, dynamic>> maps = await db.query('EquipmentRegTable');
return List.generate(maps.length, (i) {
return DataEquipmentReg(
eq_no: '${maps[i]['eq_no']}',
description'${ maps[i]['description']}',
);
});
}

Related

Error while appending data to list with custom Model class(Dart)

I am new to dart and I am trying to create a basic inventory app with different types of chemicals.
I am trying to fetch data from firebase, which is getting back to me perfectly, but when I am trying to store it locally with a custom Model Class, its throwing me the following error
type 'int' is not a subtype of type 'String'
Here is the code for fetching and storing data locally
Future<void> getLoadedData() async {
final url = Uri.parse(
'https://inventory-db0eb-default-rtdb.asia-southeast1.firebasedatabase.app/chemicalList.json?auth=$authToken');
try {
final response = await http.get(url);
final List<ChemModel> _tempChemical = [];
final _tempChemList = json.decode(response.body) as Map<String, dynamic>;
_tempChemList.forEach((elementId, value) {
_tempChemical.add(
ChemModel(
id: ' ',
name: ' ',
// name: value['name'] ?? "Empty",
formula: ' ',
// formula: value['formula'] ?? "Empty",
description: ' ',
molWeight: double.parse(value['molWeight']),
// description: value['description'] ?? "Empty",)
),
);
});
_chemicalList = _tempChemical;
notifyListeners();
} catch (error) {
print(error);
rethrow;
}}
This is my model class
class ChemModel with ChangeNotifier {
String id;
String name;
String formula;
double molWeight;
String description;
ChemModel(
{required this.id,
required this.name,
required this.formula,
this.description = "",
this.molWeight = 0});
}
I'm not sure where I am going wrong.
You can convert a value to double as follows
molWeight: value['molWeight'].toDouble(),
or
molWeight: (value['molWeight'] as int).toDouble(),
model class may be a nuisance if you share a screenshot of the data source I can help more clearly
for exp : I mean, the value from the data source is string, and if you're trying to keep it as a int in the model class, you might get this kind of error.

Flutter - _CastError (type 'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>' in type cast)

I stored a list of Map data in firestore database. But when I tried to fetch the data to a variable of type List<Map<String, dynamic>>, it shows the error "_CastError (type 'List' is not a subtype of type 'List<Map<String, dynamic>>' in type cast)".
Here is the code,
// code to fetch objects list from database
Future<List<Map<String, dynamic>>> getUserObjects() async {
Map<String, dynamic> userInfo = await getUserInfo();
List<Map<String, dynamic>> userObjects = userInfo['objects'] as List<Map<String, dynamic>>;
List<Map<String, dynamic>> result = [];
for(var i=0; i<userObjects.length; i++) {
var docInfo = await DatabaseMethods().getDocumentInfo(findCollectionName(userObjects[i]['objectType']), userObjects[i]['docId']) as Map<String, dynamic>;
result.add({'icon': findIcon(userObjects[i]['objectType']), 'objectName' : docInfo['objectName'], 'docId' : userObjects[i]['docId']});
}
return result;
}
Future<Map<String, dynamic>> getUserInfo() async {
var user = await FirebaseAuthentication().getCurrentUser();
Map<String, dynamic> userInfo = await DatabaseMethods().getuserFromDB(user.uid);
if(userInfo['objects'] == null) {
userInfo.addAll({'objects' : []});
}
return userInfo;
}
final FirebaseAuth auth = FirebaseAuth.instance;
Future<User> getCurrentUser() async {
return auth.currentUser!;
}
// code to add an object to object list in collection 'user'
Future<void> updateUserObjectList(Map<String, dynamic> object) async {
var user = await FirebaseAuthentication().getCurrentUser();
var userId = user.uid;
await FirebaseFirestore.instance.collection('users').doc(userId)
.update({'objects' : FieldValue.arrayUnion([object])});
}
The data stored in the database will look like the below image with the following changes,
replace 'quotes' with 'objects'
replace 'auther' with 'objectType'
replace 'quote' with 'docId'
replace 'user' with 'users'
Can someone say where the error happened. Code gives the error in the line "List<Map<String, dynamic>> userObjects = userInfo['objects'] as List<Map<String, dynamic>>;" in getUserObjects method
Moving the OP's solution into an answer for this question, this specific issue was caused by sending an incorrect document.id in the fetch call.
Using the correct document ID (user.id + datetime for the OP's case) solved the problem.

Flutter: Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>'

I am using Firebase and SharePreferences to store some values after authentication. I get this error "Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>'
"
I am trying to store 2 Key value pairs as JSON into the sharedPreferences.
Here is my code. User.dart
class GoogleUser {
final String displayName;
final String photoUrl;
GoogleUser(this.displayName, this.photoUrl);
GoogleUser.fromJson(Map<String, dynamic> json)
: displayName = json['displayName'],
photoUrl = json['photoUrl'];
Map<String, dynamic> toJson() =>
{'displayName': displayName, 'phototUrl': photoUrl};
}
SharedPref.dart
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class SharedPref {
saveInfo(String key, value) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(key, json.encode(value));
print("|||||||||||||||||||||||||||||||||||");
print(value);
}
deleteInfo(String key) async {
final prefs = await SharedPreferences.getInstance();
prefs.remove(key);
}
}
This the snippet which I use to save the user data, this is an file named as auth.dart, I get all the values push into sharedpreff.
void storeUserData(displayName, photoUrl) {
SharedPref sharedPref = SharedPref();
GoogleUser gUser = new GoogleUser(displayName, photoUrl);
String user = jsonEncode(gUser);
sharedPref.saveInfo('googleUser', user);
print("++++++++++++++++ Shared Prefs ++++++++++++++++++");
print(user);
}
This is the print output
This is retrieve info code, in a file login.dart
void getInfo() async {
final prefs = await SharedPreferences.getInstance();
print(prefs.getString('googleUser')!);
Map<String, dynamic> jsonData = jsonDecode(prefs.getString('googleUser')!);
var userData = GoogleUser.fromJson(jsonData);
print(
"--------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>....----------------");
print(userData.displayName);
print(userData.photoUrl);
setState(() {
//(prefs.getString('googleUser'));
});
}
This is the print output for the first print statement in this method, The string appears different compared to how it got stored, and I get error on the line just after the first print statement. I am breaking my head on what is missing here.
I referred this article to write this code, https://protocoderspoint.com/store-data-model-object-data-in-sharedpreferences-flutter/
Any help is much appreciated for a newbie Flutter developer
I thinks its this line
prefs.setString(key, json.encode(value));
it should be:
prefs.setString(key, value);
since you already encoded the user to Srting in this line
String user = jsonEncode(gUser);

Unhandled Exception: type 'String' is not a subtype of type 'DateTime' in type cast

im new in flutter
i want to get data from snapshot and load to screen but got this exception how can i fix it
sorry for my bad english
transaction_db.dart
class TransactionDB {
String dbName;
TransactionDB({required this.dbName});
//HERE I TRY TO LOAD DATA FROM LOCAL DB AND GET DATA FROM LIST<DYNAMIC> IS THIS USABLE TO GET DATA AND TAKE IT TO SCREEN
Future<List<dynamic>> loaddata() async {
var db = await opendb();
var store = intMapStoreFactory.store('expense');
//find = select find return list snapshot
var snapshot = await store.find(db);
List transactionList = <Transactions>[]; //<<< IS THIS BE LIKE COPY STRUCTOR?
for (var record in snapshot) {
transactionList.add(Transactions(
title: record['title'] as String,
subtitle: record['subtitle'] as String,
date: record['date'] as DateTime)); //<<<<<EXCEPTION BY THIS
}
return transactionList;
}
}
transaction_provider.dart
class TransactionProvider with ChangeNotifier {
List<dynamic> transactions = [];
void addTransaction(Transactions statement) async {
var db = TransactionDB(
dbName:
'transactions.db');
//select data to db
transactions = await db.loaddata();
notifyListeners();
}
}
transaction.dart
class Transactions {
String title ;
String? subtitle ;
DateTime date ;
Transactions({required this.title,required this.subtitle,required this.date});
}
Your service is returning(probably) a String type (not a DateTime type), so Dart is unable to interpretate a String into a DateTime.
For doing this, instead of date: record['date'] as DateTime use date: DateTime.parse(record['date'] as String)

Store data as an object in shared preferences in flutter

I want to store an object in shared preferences which contains some fields in it like name, age, phone number etc. I don't know how to store an object in shared preferences in flutter.
You can Store an object in shared preferences as Below:
SharedPreferences shared_User = await SharedPreferences.getInstance();
Map decode_options = jsonDecode(jsonString);
String user = jsonEncode(User.fromJson(decode_options));
shared_User.setString('user', user);
SharedPreferences shared_User = await SharedPreferences.getInstance();
Map userMap = jsonDecode(shared_User.getString('user'));
var user = User.fromJson(userMap);
class User {
final String name;
final String age;
User({this.name, this.age});
factory User.fromJson(Map<String, dynamic> parsedJson) {
return new User(
name: parsedJson['name'] ?? "",
age: parsedJson['age'] ?? "");
}
Map<String, dynamic> toJson() {
return {
"name": this.name,
"age": this.age
};
}
}
After searching a lot of articles here you are
For saving data to SharedPreferences instance, object must be converted to JSON:
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> user = {'Username':'tom','Password':'pass#123'};
bool result = await prefs.setString('user', jsonEncode(user));
For getting data from SharedPreferences instance, object must converted from JSON:
String userPref = prefs.getString('user');
Map<String,dynamic> userMap = jsonDecode(userPref) as Map<String, dynamic>;
To Save the object to Shared Preferences
SharedPreferences pref = await SharedPreferences.getInstance();
Map json = jsonDecode(jsonString);
String user = jsonEncode(UserModel.fromJson(json));
pref.setString('userData', user);
To Fetch the object from Shared Preferences
SharedPreferences pref = await SharedPreferences.getInstance();
Map json = jsonDecode(pref.getString('userData'));
var user = UserModel.fromJson(json);
You will need to import below mentioned packages
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
Easiest way to create Model
Follow this answer -> https://stackoverflow.com/a/58708634/9236994
You need to serialize it to JSON before saving and deserialize after reading
See https://flutter.io/docs/development/data-and-backend/json for details
When Getting Data from the API and Saving it Into Sharepreference
Future<UserDetails> UserInfo({String sesscode, regno}) async{
await Future.delayed(Duration(seconds: 1));
SharedPreferences preferences = await SharedPreferences.getInstance();
var map = new Map<String, String>();
map["sesscode"] = sesscode;
map["regno"] = regno;
var response = await http.post(Base_URL().user_info, body: map);
Map decodedata = json.decode(response.body);
if(decodedata != null){
String user = jsonEncode(UserDetails.fromJson(decodedata));
preferences.setString(SharePrefName.infoPref, user);
return UserDetails.fromJson(decodedata);
}
return null;
}
I Create A function for Getting the Details
You can call this function anywhere in your App
Future<UserDetails> getSavedInfo()async{
SharedPreferences preferences = await SharedPreferences.getInstance();
Map userMap = jsonDecode(preferences.getString(SharePrefName.infoPref));
UserDetails user = UserDetails.fromJson(userMap);
return user;
}
Now, Am calling it inside a Class to get username
Future<UserDetails> usd = getSavedInfo();
usd.then((value){
print(value.surname);
});
SharePreferences Handler
I have created a LocalStorageRepository class, that is responsible to handle local data using SharedPreferences.
The class is dynamic and can work with any type of data (int, double, bool, String, and Object) using generics and JSON decoding and encoding.
In order to prevent pron errors, I added the LocalStorageKeys enum to handle the supported keys. Feel free to add more keys to that enum.
enum LocalStorageKeys { tutorialCompleted, user }
#singleton
class LocalStorageRepository {
const LocalStorageRepository(SharedPreferences prefs) : _prefs = prefs;
final SharedPreferences _prefs;
bool keyExists(String key) => _prefs.containsKey(key);
T? getValue<T>(
LocalStorageKeys key, [
T Function(Map<String, dynamic>)? fromJson,
]) {
switch (T) {
case int:
return _prefs.getInt(key.name) as T?;
case double:
return _prefs.getDouble(key.name) as T?;
case String:
return _prefs.getString(key.name) as T?;
case bool:
return _prefs.getBool(key.name) as T?;
default:
assert(fromJson != null, 'fromJson must be provided for Object values');
if (fromJson != null) {
final stringObject = _prefs.getString(key.name);
if (stringObject == null) return null;
final jsonObject = jsonDecode(stringObject) as Map<String, dynamic>;
return fromJson(jsonObject);
}
}
return null;
}
void setValue<T>(LocalStorageKeys key, T value) {
switch (T) {
case int:
_prefs.setInt(key.name, value as int);
break;
case double:
_prefs.setDouble(key.name, value as double);
break;
case String:
_prefs.setString(key.name, value as String);
break;
case bool:
_prefs.setBool(key.name, value as bool);
break;
default:
assert(
value is Map<String, dynamic>,
'value must be int, double, String, bool or Map<String, dynamic>',
);
final stringObject = jsonEncode(value);
_prefs.setString(key.name, stringObject);
}
}
}
In case you want to get an Object value from LocalStorageRepository, you will need to provide its fromJson decoder.
final user = _localStorage.getValue(LocalStorageKeys.user, User.fromJson);
Hope that hence example will help others out there.
Feel free to edit this question and suggest any changes.
If you are getting you data from an API, what you initially get from an API endpoint is a String so you can store the data as a raw String and when you need it you can deserialize it and use where you want to use it
https://gist.github.com/k1ycee/33bb7e51dac81093f949bbd30d7d0dc9
Something like this, the drawback I feel is that if the JSON string data is much might not be advisable to store all the string rather deserialize it and take the ones you deem necessary.