Getting an error when everything's supposed to work - flutter

I'm building an app with Flutter where you can add files to the app's cache.
There are 2 things that are not working, which I don't understand why.
Here's the source
Whenever I launch the app for the first time (with absolutely no cache) I get this error
Directory listing failed, path = '/data/user/0/com.example.lockedapp/cache/file_picker/' (OS Error:
No such file or directory, errno = 2)
Even though I made precautions to create the directory before trying to display it.
bool checkFilesEmpty() {
var cache = new Directory('/data/user/0/com.example.lockedapp/cache/file_picker');
cache.exists().then((resp) => { if (!resp) { cache.create() } }); // creates a new cache directory if it does not exist
return cache.listSync(recursive: false).toList().length != 0; // returns false if it's empty
}
on line 31, the checkFilesEmpty is checked first and then comes everything else, but i still get the error.
the weird thing is that if I relaunch the app, it works as it's intended.
Any solutions for this? I'm really confused

Put your checkFilesEmpty in initState method of Stateful widget hence it will be called on before your widget is building.
class MyHomeState extends State<MyHome> {
bool filesEmpty;
#override
void initState() {
super.initState();
filesEmpty = checkFilesEmpty();
}
.
. // Your rest of code
.
}
You can put your error causing statement in try catch block. If there is no listing then you can create one in catch block:
bool checkFilesEmpty() {
try{
var cache = new Directory('/data/user/0/com.example.lockedapp/cache/file_picker');
return cache.listSync(recursive: false).toList().length != 0;
}
catch{
cache = Directory('/data/user/0/com.example.lockedapp/cache/file_picker').create() ;
return cache.listSync(recursive: false).toList().length != 0;
}
}

Related

How to handle lists initial building in Getx

I'm making a reactive model with Getx on a product list, but when I start the list it comes with no value and causes an index error even though there are actually values ​​in the list it appears empty at first, which somehow gets fixed automatically. (this is inside a build of a statelesswidget)
return GetX<CartController>(
init: CartController(),
builder: (controller) {
try {
return Text(
"${StringConvert.toMoney(controller.totalByProduct[productId])}",
style: kSmallTextBold,
);
} catch (e) {
return const Text("Error...");
}
},
);
}
I did try catch to manage this, but the catch part doesn't show up;
this is relevant part of the controller
var totalByProduct = [].obs;
fetchTotal() {
List products = storage.read(StorageKeys.cartProducts);
double currentValue = 0.0;
List currentTotals = [];
for (var item in products) {
currentTotals.add(item['total'] * item['amount']);
currentValue += item['total'] * item['amount'];
}
total.value = currentValue;
totalByProduct.value = currentTotals;
}
I believe it's not the right way to do this, so what do I need to know to fix this correctly?
If helps this is the error:
With a method to read the storage (sharedPreferences) in async mode, with a FutureBuilder it was possible to correct the error, because in the initial state the list takes the value assigned explicitly. Even if it then receives the correct value, accessing the index in its initial state causes the error, this explains why even with the error it works.

Flutter Signalr Listener is not connected in 2nd screen after migrated to null safety stable version

Chatting was working perfectly before migrating to null safety using signalr. But after migrating It is not working in chatting part.
Scenario is like there are 2 screens where I am using signalr.
1)Chatlist.
2)Chatting with person.
listener in Chatlist is perfect but in 2nd screen it is not working(Just worked when I installed and run for the 1st time). Weird issue.
All was working in old. I am using bloc for statemanagement and also migrated to yield to emit.
Piece of code is like:
void listenOnMessageReceived(
HubConnection hubConnection,
Function(Message? chatMessageReceive) onMessageReceived,
) {
final SocketResponseCallBack chatMessageReceived =
(response) => onMessageReceived(Message.fromJson(response));
final hubMethod = HubMethod(
CHAT_RECEIVED_MESSAGE_METHOD_NAME,
SignalRHelper.toSocketFunction(
CHAT_RECEIVED_MESSAGE_METHOD_NAME, chatMessageReceived));
bool exists = listenOnHubMethod.any((method) => method.methodName == CHAT_RECEIVED_MESSAGE_METHOD_NAME);
if(exists) {
listenOnHubMethod.removeWhere((element) =>
element.methodName == CHAT_RECEIVED_MESSAGE_METHOD_NAME);
SignalRHelper(hubConnection: hubConnection).on(
hubMethod.methodName,
hubMethod.methodFunction,
);
listenOnHubMethod.add(hubMethod);
}else{
SignalRHelper(hubConnection: hubConnection).on(
hubMethod.methodName,
hubMethod.methodFunction,
);
listenOnHubMethod.add(hubMethod);
}
}
I am having 2 types of above code in different screens. but it is working in only 1 screen and not listening in 2nd screen.
here is a piece of signalr listener code:
static MethodInvocationFunc toSocketFunction(
String methodName, SocketResponseCallBack responseCallBack) {
return (arguments) {
try {
if (arguments!.isEmpty) {
throw SocketEmptyResponseException(methodName);
}
final response = arguments.first;
responseCallBack(response);
} on FormatException {
throw SocketResponseException(methodName);
}
};
}
Is there any limitations in migration of stable version or anything else. Every help is appreciable.
Thank you.
Do not use signalR, on IOS it will be impossible to run listener on background or when app is closed and you will miss messages. Use FCM.

why the dart function did not return the sub function result

I am now using this functon to fetch new music in flutter:
class QuietPlayQueueInterceptor extends PlayQueueInterceptor {
#override
Future<List<MusicMetadata>> fetchMoreMusic(BackgroundPlayQueue queue, PlayMode playMode) async {
if (queue.queueId == kFmPlayQueueId) {
final musics = await (neteaseRepository!.getPersonalFmMusicsFromQueue() as FutureOr<List<Music>>);
final musicListExt= musics.toMetadataList();
return musicListExt;
}
return super.fetchMoreMusic(queue, playMode);
}
}
and this is the function getPersonalFmMusicsFromQueue define:
Future<List<Music>?> getPersonalFmMusicsFromQueue() async {
if(fmPlayQueue.isEmpty){
return getPersonalFmMusics();
}else{
final Music music = fmPlayQueue.first;
final List<Music> musics = List.empty(growable: true);
musics.add(music);
return Future.value(musics);
}
}
what makes me confusing is that the getPersonalFmMusicsFromQueue function did not return any result. I make a breakpoint on the line final musicListExt= musics.toMetadataList(); but did not hited. The console is no error output. where am I doing wrong? what should I do to fix this problem?
getPersonalFmMusics looks asynchronous? Perhaps you're not awaiting
Future<List<Music>?> getPersonalFmMusicsFromQueue() async {
if(fmPlayQueue.isEmpty){
return await getPersonalFmMusics();
}
// ...
I would also advise against casting unless you're sure you need it. Instead, have the return type of getPersonalFmMusicsFromQueue return a FutureOr
(neteaseRepository!.getPersonalFmMusicsFromQueue() as FutureOr<List<Music>>); // Remove FutureOr<List<Music>>
// and make the function signature instead look like this:
FutureOr<List<Music>> getPersonalFmMusicsFromQueue(); // Force unwrapping with a `!` but also throwing proper exceptions when null.
The reason being is that casting usually hides errors the compiler would otherwise be warning you about.
Another idea I have if the above isn't the issue is the .first call.
final Music music = fmPlayQueue.first;
If this is a first getter on a stream then that need to be awaited and it likely isn't working because it's just indefinitely waiting for the stream to output a value.

How to fix Flutter stream exiting whenever i try to listen to it

In a flutter app, I'm trying to read a large csv file one line at a time by opening a stream on it. The issue is that when i try to listen to the stream the execution just skips over that code block and the program ends.
The file I'm opening is located in my assets folder and I've confirmed programmatically that it does exist before opening the stream. Changing the file the stream is opened on doesn't help, the same problem persists. I've also tried to change the way i listen to the stream, following different methods provided by Darts official documentation (that code is commented out) but the outcome is again the same. The assets have been declared in the pubspec.yaml. When i change the code to read the file as a String the program works perfectly but I want to use a stream because the file is so massive that creating a String object for it would take a large amount of time and memory.
void trainDigitsStream() async{
List<List<List>> filters = createRandomFilter(4, 4, 1, -1, 1);
List flattened= new List<double>();
File file = new File("assets/digit_train_data.csv");
if(file.existsSync())print("EXISTS!");
Stream<List<int>> stream = file.openRead();
Stream lines = utf8.decoder.bind(stream).transform(LineSplitter());
/*
try{
await for (var line in lines){
print(line);
}
print("file ended");
}catch(e){
print(e);
}
*/
lines.listen((data){//code exits here, execution never reaches next line
String line = data.toString();
List<List> instance = new List<List<int>>();
List x = new List<int>();
int i = 0;
line.split(',').forEach((d){
x.add(int.parse(d));
i++;
if(i == 28){
instance.add(x);
x = new List<int>();
i = 0;
}
});
List<List<List>> kernels = new List<List<List<double>>>();
List<List> pools = new List<List>();
filters.forEach((f){kernels.add(convo.applyFilter(instance, f, 0));});
kernels.forEach((k){pools.add(pool.maxPool(k, 2));});
pools.forEach((p){flattened.addAll(p);});
});
}
It's hard without further information, It would be better if you can post more information.
So I guess the problem should be , please check the following two steps.
1. Register the assets folder in pubspec.yaml
flutter:
assets:
- assets/digit_train_data.csv
2. You need to use rootBundle to access this csv file, reference document https://flutter.dev/docs/development/ui/assets-and-images
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/digit_train_data.csv');
}
similar question here Flutter - Read text file from assets

Akavache not working in Windows 8.1 Universal App

I’m trying to make work Akavache in a Windows Universal Application (8.1 for now, using ReactiveUI 6.5).
To make sure that it is not related to my architecture, I did an empty solution that has all the necessary packages and requirements (VC++ for both platforms), and I still get the same issue. This is a blocker for me since I want all my queries to be cached.
Here's the code:
BlobCache.ApplicationName = "MyApp"; // In AppBootstrapper`
// In My ViewModel
SubmitCommand = ReactiveCommand.CreateAsyncTask(async _ =>
{
var isTrue = await BlobCache.UserAccount.GetOrFetchObject("login_credentials",
async () => await Task.FromResult(true)
);
// My Code never goes further than this
if (!isTrue)
{
throw new Exception("I'm false!");
}
return isTrue;
});
SubmitCommand.Subscribe(isTrue => {
Debug.WriteLine("I got a new value!");
});
SubmitCommand.ThrownExceptions.Subscribe(ex => {
UserError.Throw(ex.Message, ex);
});
// In The View
ViewModel = new MainPageViewModel();
this.BindCommand(ViewModel, x => x.SubmitCommand, x => x.SubmitCommand);
public MainPageViewModel ViewModel
{
get { return (MainPageViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(MainPageViewModel), typeof(MainPage), new PropertyMetadata(null));
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (MainPageViewModel)value; }
}
Edit After some debug, Windows Phone 8.1 Silverlight works, not Jupiter.
So what's missing?
I'm using RXUI 6.5 (latest) with a Windows Phone 8.1 (Jupiter) (with shared Universal Projects)
Updated: Akavache.Sqlite3 is causing the issue. InMemoryCache is working (removing Akavache.Sqlite3 "fixes" the problem), but not Sqlite3.
Also, registering BlobCache's different types of cache (copy paste from https://github.com/akavache/Akavache/blob/3c1431250ae94d25cf7ac9637528f4445b131317/Akavache.Sqlite3/Registrations.cs#L32) is working apparently.. so I suppose the Registration class aren't working properly and calling
new Akavache.Sqlite3.Registrations().Register(Locator.CurrentMutable); is not working.
Edit: My temporary solution is to copy paste this into my application, and I invoke it after BlobCache.ApplicationName. It works, but I shouldn't technically have to do that.
Thanks for your help