Save a List to SharedPreferences - flutter

I am trying to save the list dragged from the sql to be saved in SharedPreferences, I tried using this code:
static Future<List<User>> getUsers() async {
final myUserId = await getUser();
try {
var myUser = myUserId;
var map = Map<String, dynamic>();
map['user'] = myUser;
final response = await http.post(ROOT, body: map);
//print('getUsers Response: ${response.body}');
//print(myUser);
if (200 == response.statusCode) {
List<User> listContacts = parseResponse(response.body);
SharedPreferences contacts = await SharedPreferences.getInstance();
contacts.setStringList('contacts', listContacts);
return listContacts;
} else {
return List<User>();
}
} catch (e) {
return List<User>(); // return an empty list on exception/error
}
}
the User class for the list is the following:
class User {
final String firstName;
final String lastName;
final String imageLink;
User({this.firstName, this.lastName, this.imageLink});
factory User.fromJson(Map<String, dynamic> json) {
return User(
firstName: json['firstName'] as String,
lastName: json['lastName'] as String,
imageLink: json['imageLink'] as String,
);
}
}
So basically the data is successfully pulling it out from the database, and it does display it, but I want to save the data to SharedPreferences so it doesn't have to load every single time. The error that is occurring is that the listContacts can't be assigned to setStringList, since it is a List<User> and not a List<String>, but I don't know how else can I change the code in order to be able to set the SharedPreferences.

Here you can do is
static Future<List<User>> getUsers() async {
final myUserId = await getUser();
try {
var myUser = myUserId;
var map = Map<String, dynamic>();
map['user'] = myUser;
final response = await http.post(ROOT, body: map);
//print('getUsers Response: ${response.body}');
//print(myUser);
if (200 == response.statusCode) {
List<User> listContacts = parseResponse(response.body);
SharedPreferences contacts = await SharedPreferences.getInstance();
contacts.setString('contacts',json.encode(response.body)); //Here saved the response
return listContacts;
} else {
return List<User>();
}
} catch (e) {
return List<User>(); // return an empty list on exception/error
}
}
Now to fetch it I can use is
SharedPreferences contacts = await SharedPreferences.getInstance();
var response = json.decode(contacts.getString('contacts'));
List<User> listContacts = parseResponse(response.body);
and you get back your data from shared preferences

Related

How toGet data from api and save it into local database sqlite then show in listview (from local)

How to get data from api and save the data to locally database sqlite?
this is my code, but still got error in dio
can you guys help me
error dio
import 'package:bloggggg/employee_model.dart';
import 'package:bloggggg/db_provider.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart';
class EmployeeApiProvider {
Future<List<Employee?>> getAllEmployees() async {
final url = "http://demo8161595.mockable.io/employee";
Response response = await Dio().get(url);
if(response.statusCode == 200){
return (response.data as List).map((employee) {
print('Inserting $employee');
DBProvider.db.createEmployee(Employee.fromJson(employee));
}).toList();
}else{
return response.data;
}
}
}
Save Api Data Function
save() async {
final dbHelper = DatabaseHelper.instance;
const url = "http://demo8161595.mockable.io/employee";
final result = await get(Uri.parse(url));
final response = jsonDecode(result.body);
Map<String, dynamic> row = DatabaseInsetItemModel(
name: response["name"] ?? "",
lName: response["lName"] ?? "",
mobile: response["mobile"] ?? "",
email: response["email"] ?? "",
cat: response["cat"] ?? "",
profile: response["profile"] ?? "")
.toJson();
print('insert stRT');
final id = await dbHelper.insertContact(row);
if (kDebugMode) {
print('inserted row id: $id');
}
}
DataBase Helper
class DatabaseHelper {
static final _databaseName = "MyDatabase.db";
static final _databaseVersion = 1;
static final table = 'category';
static final tableContact = 'contact';
static final columnId = '_id';
static final columnName = 'name';
static final columnLName = 'lname';
static final columnMobile = 'mobile';
static final columnEmail = 'email';
static final columnCategory = 'cat';
static final columnProfile = 'profile';
// make this a singleton class
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
// only have a single app-wide reference to the database
static Database? _database;
Future<Database> get database async => _database ??= await _initDatabase();
Future<Database?> get database1 async {
if (_database == null) {
_database = await _initDatabase();
}
return _database;
}
// this opens the database (and creates it if it doesn't exist)
_initDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, _databaseName);
return await openDatabase(path,
version: _databaseVersion, onCreate: _onCreate);
}
// SQL code to create the database table
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $table (
$columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL
)
''');
await db.execute('''
CREATE TABLE $tableContact (
$columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL,
$columnLName TEXT NOT NULL,
$columnMobile TEXT NOT NULL,
$columnEmail TEXT NOT NULL,
$columnCategory TEXT NOT NULL,
$columnProfile TEXT NOT NULL
)
''');
}
// Helper methods
// Inserts a row in the database where each key in the Map is a column name
// and the value is the column value. The return value is the id of the
// inserted row.
Future<int> insert(Map<String, dynamic> row) async {
Database? db = await instance.database;
return await db.insert(table, row);
}
Future<int> insertContact(Map<String, dynamic> row) async {
Database? db = await instance.database;
return await db.insert(tableContact, row);
}
// All of the rows are returned as a list of maps, where each map is
// a key-value list of columns.
Future<List<Map<String, dynamic>>> queryAllRows() async {
Database db = await instance.database;
return await db.query(table);
}
Future<List<Map<String, dynamic>>> queryAllRowsofContact() async {
Database db = await instance.database;
return await db.query(tableContact);
}
// All of the methods (insert, query, update, delete) can also be done using
// raw SQL commands. This method uses a raw query to give the row count.
Future<int> queryRowCount() async {
Database db = await instance.database;
return Sqflite.firstIntValue(
await db.rawQuery('SELECT COUNT(*) FROM $table')) ??
0;
}
// We are assuming here that the id column in the map is set. The other
// column values will be used to update the row.
Future<int> update(Map<String, dynamic> row) async {
Database db = await instance.database;
int id = row[columnId];
return await db.update(table, row, where: '$columnId = ?', whereArgs: [id]);
}
// Deletes the row specified by the id. The number of affected rows is
// returned. This should be 1 as long as the row exists.
Future<int> delete(int id) async {
Database db = await instance.database;
return await db.delete(table, where: '$columnId = ?', whereArgs: [id]);
}
Future<int> deleteContact(int id) async {
Database db = await instance.database;
return await db.delete(tableContact, where: '$columnId = ?', whereArgs: [id]);
}
}
DataBase Item Model
class DatabaseInsetItemModel{
String? name;
String? lName;
String? mobile;
String? email;
String? cat;
String? profile;
DatabaseInsetItemModel(
{required this.name, required this.lName, required this.mobile, required this.email, required this.cat, required this.profile});
DatabaseInsetItemModel.fromJson(Map<String, dynamic> json) {
name = json['postId'];
lName = json['id'];
mobile = json['name'];
email = json['email'];
cat = json['body'];
profile = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data[DatabaseHelper.columnName] = name;
data[DatabaseHelper.columnLName] = lName;
data[DatabaseHelper.columnMobile] = mobile;
data[DatabaseHelper.columnEmail] = email;
data[DatabaseHelper.columnCategory] = cat;
return data;
}
}
Show Data on screen
class ShowPostScreen extends StatefulWidget {
ShowPostScreen({Key? key}) : super(key: key);
#override
State<ShowPostScreen> createState() => _ShowPostScreenState();
}
class _ShowPostScreenState extends State<ShowPostScreen> {
final dbHelper = DatabaseHelper.instance;
List<DatabaseInsetItemModel> data = [];
#override
void initState() {
// TODO: implement initState
dbHelper.queryAllRows().then((value) {
setState(() {
data = value.map((e) => DatabaseInsetItemModel.fromJson(e)).toList();
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Text(data[index].name ?? "");
},
),
);
}
}

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('');

Flutter Exception Handling Show error message when the user enteres incorrect city name

I am using one of openweathermap to get the latitude and longitude based on a city name.
Whenever the user enters an invalid city name, this is the response from the api.
How can I catch this and show an error message to the user.
This is the function that makes the api call.
Constants myConstaints = Constants();
Future<CityInfo> gettingCityData(String cityName) async {
var url = Uri.parse(
'https://api.openweathermap.org/geo/1.0/direct?q=$cityName&limit=1&appid=${myConstaints.apiKey}');
var response = await http.get(url);
if (response.statusCode == 200) {
var i = CityInfo.fromJson(jsonDecode(response.body));
return i;
} else
throw Exception('error');
}
CityInfo class and its constructor
class CityInfo {
String name;
double lat;
double long;
CityInfo.fromJson(List<dynamic> json)
: name = json[0]['name'],
lat = json[0]['lat'].toDouble(),
long = json[0]['lon'].toDouble();
}
Provider
Future<void> cityName(String cityName) async {
cityInfo = await gettingCityData(cityName);
notifyListeners();
}
The API is returning a list of cities. It may return an empty list.
First of all, the CityInfo.fromJson should not take a list as input. It should rather only focus on converting a CityInfo JSON object to a CityInfo object.
class CityInfo {
String name;
double lat;
double long;
CityInfo.fromJson(Map<String, dynamic> json)
: name = json['name'],
lat = json['lat'].toDouble(),
long = json['lon'].toDouble();
}
Now, notice how CityInfo can be null so your future should return a nullable CityInfo
Future<CityInfo?> gettingCityData(String cityName)
Now to handle the request,
Future<CityInfo?> gettingCityData(String cityName) async {
final url = Uri.parse(
'https://api.openweathermap.org/geo/1.0/direct?q=$cityName&limit=1&appid=${myConstaints.apiKey}');
final response = await http.get(url);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
if (data.isEmpty) return null; // List is empty.
final cityJson = data.first as Map<String, dynamic>;
return CityInfo.fromJson(cityJson);
} else
throw Exception('Error');
}
}
Now, the method can be called as,
Future<void> cityName(String cityName) async {
cityInfo = await gettingCityData(cityName);
if (cityInfo == null) {
// City was not found. Show some message here.
}
notifyListeners();
}

How to save a list of objects locally in Flutter?

I have a page from which I need to save data locally as a list. To save, I use SharedPrefs, there, through the model, I save the data as a list. But I ran into a problem that I can not specify the format for receiving data List, tell me how can I save data as a list and receive data as a list?
class RecentlySearchedModel {
String name;
String address;
RecentlySearchedModel({
required this.name,
required this.address,
});
factory RecentlySearchedModel.fromJson(Map<String, dynamic> json) {
return RecentlySearchedModel(
name: json['name'] as String,
address: json['address'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'address': address,
};
}
}
repository
#override
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonEncode( ))
}
#override
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
return List<RecentlySearchedModel>.fromJson(
jsonDecode(data),
);
}
update your repository like this.
#override
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonEncode(searchedList.toJson());
}
#override
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
Iterable l = json.decode(data);
List<RecentlySearchedModel> posts = List<RecentlySearchedModel>.from(l.map((model)=> RecentlySearchedModel.fromJson(model)));
return posts;
}
i havent try to complie, but its should be like this
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
List<Map<String,dynamic>> listItem = searchedList.map((e)=> e.toJson()).toList();
String jsonString = jsonEncode(listItem);
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonString)
}
and get it back
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
return (jsonDecode(data) as List).map((e)=> RecentlySearchedModel.fromJson(e)).toList();
}

About Firebase real time database

I am working on Firebase real time databases in Flutter. I am storing user information and their corresponding data in database. My code is given below:
//User Auth Class
class UserAuth{
final String id;
final String email;
final String token;
UserAuth({#required this.id, #required this.email, #required this.token});
}
//User Details Class for storing data of corresponding user
class UserDetails{
final String userDetailsId;
final String name;
final String email;
UserDetails({#required this.userDetailsId,#required this.name, #required this.email});
}
//I am using this code to add userDetails in database.
List<UserDetails> _detailsList = [];
UserDetails _details;
Future<bool> addUserDetails(String username, String email) async {
_isLoading = true;
notifyListeners();
final Map<String, dynamic> userDetails = {
'username': username,
'email': email,
};
try {
final http.Response response = await http.post(
'https://intro-to-firebase-711d4.firebaseio.com/Users.json',
body: json.encode(userDetails));
if (response.statusCode != 200 && response.statusCode != 201) {
_isLoading = false;
notifyListeners();
return false;
}
final Map<String, dynamic> responseData = json.decode(response.body);
_details = UserDetails(
userDetailsId: responseData['name'], name: username, email: email);
_detailsList.add(_details);
_isLoading = false;
notifyListeners();
return true;
} catch (error) {
_isLoading = false;
notifyListeners();
return false;
}
}
Now I want to get the following highlighted ids of the user so how to fetch it. I am using scoped model as a state management in Flutter.
I did it with javascript so far but in the documentation it seems not taht different for flutter:
private void writeNewUser(String userId, String name, String email) {
User user = new User(name, email);
mDatabase.child("users").child(userId).setValue(user);
}
https://firebase.google.com/docs/database/android/read-and-write?authuser=0
This is the example shown in the docs. with .child('users') you can get the right section .child(userId) gives you access to the values.
All you have to do now is defining the variable userId
flutter
you can achieve this as follows
stream: FirebaseDatabase.instance
.reference()
.child('users')
.equalTo(userId)
.onValue,