I have an app that plays a sound. There is a list of sounds and I show that to an listview. So user can click a listtile and plays a sound. And I added a "Favourite" section. And it works fine. But when user closes the app it goes away. I tried to use SharedPrefences but I couldnt manage to do it. Because I need to save the whole list and I dont know how.
When I close the app, all my 'favourite' list goes away.
I will just share all the codes for better understanding:
Main.dart
Favourite.dart
Here is the explaining with the pictures:
Since the list of saved songs is a list of Strings you can use setStringList() method from SharedPrefences. When you want to save the list, use:
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('savedSounds', savedSounds);
Then when the application starts you load the songs by using:
final prefs = await SharedPreferences.getInstance();
savedSounds = prefs.getStringList('savedSounds') ?? [];
Then you can use a for-loop to also get the saved indexes, although I would recommend you to try only using one list of the saved songs.
for(int i = 0; i < savedSounds.length; i++){
if(soundList[i] == savedSounds[i]){
savedIndex.add(i.toString());
}
}
You can use the SQFlite package to store your List items locally. Here is the package:
https://pub.dev/packages/sqflite
Related
I am using Clean Architecture in Flutter with Getx as State Management.
I have a list that i am taking from backend and i am showing it in UI and user can do some changes to this list as well.
where is the best place to store the data that is taken from backend and show from and change data.
right now in this example
the data is stored in Getx Controller.is this approach correct?or there is a better way?
class Controller extends GetxController{
List<Data> lsData = [];
fetchApi()async{
lsData = await fetchApi();
update();
}
add(Data data){
lsData.add(data);
update();
}
postApi()async{
await post(lsData);
}
}
there are many ways to save data in flutter, if you want to save data local there is Hive(i like this), Share preference, SQlite,GetX Storage and more
if you want to save data online I recommend Firestore
Hope this can be helpful :)
I need to upload a list of images into a storage, but I don't want to upload and await for every single image after the other, because it takes quite some time.
I would like to upload them simultaneously, like in different threads.
There is a way to do achieve multithreading with standard dart async? Or should I use Isolates?
Do you have some sample code?
You can use them in a single future
final results = await Future.wait([
uploadFunction(image1)
uploadFunction(image2)
]);
you can start uploading all images without waiting for the previous one to complete await will be returned once both uploads are completed
You can use Queue
Whats it will do it will hold your actions and you can do other task while uploading images
import 'package:dart_queue/dart_queue.dart';
main() async {
final queue = Queue(parallel: 2);
final result1 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
final result2 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Thats it!
}
By using this you dont need to add await.
NOTE: Make sure app is running while this queue is active.
I want to call a function when app runs for the first time, which will ask the user to enter firstName , lastName and add a profile picture.
Once the above process is done the function will never again be called during the lifetime of the app.
For something like this you need to check if the user has already entered that data or not. If not then show him the page where he can enter information otherwise take him to HomePage. For this When the user enters the information you need to save it to some persistent storage and check it whenever the app runs. In this way, your function will be called only once until the user deletes the app or clear its memory. You could use the following libraries to store the data.
Hive,
Shared Preference
These libraries save the data in key-value pair and read data faster especially hive.
Use SharePreference
see below code snippet with little advancement in code you can achieve your result.
Future<bool> isFirstTime() async {
var firstTime = SharedPref.pref.getBool('first_time');
if (firstTime != null && !firstTime) {
SharedPref.pref.setBool('first_time', false);
return false;
} else {
SharedPref.pref.setBool('first_time', false);
return true;
}
}
I am building an app in flutter and I want to store many images. So will anyone suggest me where I can store the images which is easy to use in my app. I mean should I store it locally or in cloud? If yes which cloud or backend should I use, whichone is good and fully optimized for my flutter app (like mongo, django, firebase etc. ). Will anyone suggest me the best?
Anyone kind of help is appreaciated as I have no prior knowledge about the production part....
Storing Images on a server can be very expensive, since the file sizes are very large compared to the usual data. So if you do not NEED to store them on a server, don't.
Storing images locally is pretty simple. You will want to use the path_provider package https://pub.dev/packages/path_provider . I ll post a function I am using in my current project that does this. You ll see, its pretty simple.
Note: In my Code I pull the file from my server. Obviously leave that part out if you are getting your images from a different source.
Future<File> createFileOfPdfUrl(String fileLocation, String name) async {
final url = Helper.baseUrl + "Files/Newsletter/" + fileLocation;
final filename = url.substring(url.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await pathProvider.getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
}
I have a flutter application where I am using the SQFLITE plugin to fetch data from SQLite DB. Here I am facing a weird problem. As per my understanding, we use either async/await or then() function for async programming.
Here I have a db.query() method which is conducting some SQL queries to fetch data from the DB. After this function fetches the data, we do some further processing in the .then() function. However, in this approach, I was facing some issues. From where I am calling this getExpensesByFundId(int fundId)function, it doesn't seem to fetch the data properly. It's supposed to return Future> object which will be then converted to List when the data is available. But when I call it doesn't work.
However, I just did some experimentation with it and added "await" keyword in front of the db.query() function and somehow it just started to work fine. Can you explain why adding the await keyword is solving this issue? I thought when using .then() function, we don't need to use the await keyword.
Here are my codes:
Future<List<Expense>> getExpensesByFundId(int fundId) async {
Database db = await database;
List<Expense> expenseList = List();
// The await in the below line is what I'm talking about
await db.query(expTable,where: '$expTable.$expFundId = $fundId')
.then((List<Map<String,dynamic>> expList){
expList.forEach((Map<String, dynamic> expMap){
expenseList.add(Expense.fromMap(expMap));
});
});
return expenseList;
}
In simple words:
await is meant to interrupt the process flow until the async method has finished.
then however does not interrupt the process flow (meaning the next instructions will be executed) but enables you to run code when the async method is finished.
In your example, you cannot achieve what you want when you use then because the code is not 'waiting' and the return statement is processed and thus returns an empty list.
When you add the await, you explicitly say: 'don't go further until my Future method is completed (namely the then part).
You could write your code as follows to achieve the same result using only await:
Future<List<Expense>> getExpensesByFundId(int fundId) async {
Database db = await database;
List<Expense> expenseList = List();
List<Map<String,dynamic>> expList = await db.query(expTable,where: '$expTable.$expFundId = $fundId');
expList.forEach((Map<String, dynamic> expMap) {
expenseList.add(Expense.fromMap(expMap));
});
return expenseList;
}
You could also choose to use only the then part, but you need to ensure that you call getExpensesByFundId properly afterwards:
Future<List<Expense>> getExpensesByFundId(int fundId) async {
Database db = await database;
List<Expense> expenseList = List();
return db.query(expTable,where: '$expTable.$expFundId = $fundId')
.then((List<Map<String,dynamic>> expList){
expList.forEach((Map<String, dynamic> expMap){
expenseList.add(Expense.fromMap(expMap));
});
});
}
// call either with an await
List<Expense> list = await getExpensesByFundId(1);
// or with a then (knowing that this will not interrupt the process flow and process the next instruction
getExpensesByFundId(1).then((List<Expense> l) { /*...*/ });
Adding to the above answers.
Flutter Application is said to be a step by step execution of code, but it's not like that.
There are a lot of events going to be triggered in the lifecycle of applications like Click Event, Timers, and all. There must be some code that should be running in the background thread.
How background work execute:
So there are two Queues
Microtask Queue
Event Queue
Microtask Queue runs the code which not supposed to be run by any event(click, timer, etc). It can contain both sync and async work.
Event Queue runs when any external click event occurs in the application like Click event, then that block execution done inside the event loop.
The below diagram will explain in detail how execution will proceed.
Note: At any given point of application development Microtask queue will run then only Event Queue will be able to run.
When making class use async for using await its simple logic to make a wait state in your function until your data is retrieve to show.
Example: 1) Its like when you follow click button 2) Data first store in database than Future function use to retrieve data 3) Move that data into variable and than show in screen 4) Variable show like increment in your following/profile.
And then is use one by one step of code, store data in variable and then move to next.
Example: If I click in follow button until data store in variable it continuously retrieve some data to store and not allow next function to run, and if one task is complete than move to another.
Same as your question i was also doing experiment in social media flutter app and this is my understanding. I hope this would help.
A Flutter question from an answer from your answer.
await is meant to interrupt the process flow until the async method has finished. then however does not interrupt the process flow but enables you to run code when the async method is finished. So, I am asking diff. between top down & bottom down process in programming.