flutter Using flutter csv package with rootBundle - flutter

I am trying to load a csv file from assets folder which is set correctly in YAML file using csv package, but i am getting this error.
The argument type 'Future' can't be assigned to the parameter
type 'String?'.dartargument_type_not_assignable The instance member
'csvFile' can't be accessed in an initializer. Try replacing the
reference to the instance member with a different expression
I am aware that CsvToListConverter takes a string as an argument instead of Future<String>.
final csvFile = rootBundle.loadString('assets/csv_file.txt');
final csvToLIst = CsvToListConverter(eol: '\n\r', fieldDelimiter: '\t')
.convert(csvFile);
I was able read the csv file with File from dart:io. But when I build the app It kinda looses the relative path to the csv file. That's the whole point to use rootBundle I guess.

AssetBundle#loadString returns a Future<String>, so you must await it:
final csvFile = await rootBundle.loadString('assets/csv_file.txt');
final csvToLIst = CsvToListConverter(eol: '\n\r', fieldDelimiter: '\t').convert(csvFile);
Note that await must only be called in an async environment. You can read more here.

rootBundle.loadString returns a Future, so you must await it:
you should wrap your function with async first and add await in the future returning method
getWorkDone() async{
final csvFile = await rootBundle.loadString('assets/csv_file.txt');
final csvToLIst = CsvToListConverter(eol: '\n\r', fieldDelimiter: '\t')
.convert(csvFile);
}

Related

Upload Blob Url to Firebase Storage | Flutter

So I already read about the topic but I simply didn't understand the solutions on stack.
I came up with this code:
Im saving a url looking like this:
final String myDataUrl = file.url;
print(myDataUrl);
blob:http://localhost:51947/2952a3b1-db6a-4882-a42a-8e1bf0a0ad73
& then Im trying to add it into Firebase Storage with the putString operator, that I guessed that suited me best while reading the Documentation. I thought that I have a Url and therefore should be able to upload it like this:
FirebaseStorage.instance
.ref()
.child("bla")
.putString(myDataUrl, format: PutStringFormat.dataUrl);
But it doesn't work, it says that:
Error: Invalid argument (uri): Scheme must be 'data': Instance of '_Uri'
So Im guessing that it somehow can't format my url to one that is accepted.
What can I do different to upload a blob successfully to firebase Storage?
-----------------Answer----------------------
Answer in the comment of the answer.
You have to convert your Blob to a Uint8List & upload it like:
Future<Uint8List> fileConverter() async {
final reader = html.FileReader();
reader.readAsArrayBuffer(file!);
await reader.onLoad.first;
return reader.result as Uint8List;
}
and then put it into your Storage:
Future uploadFile(String uid) async {
if (file == null) return;
final path = "nachweise/$uid";
Uint8List fileConverted = await fileConverter();
try {
FirebaseStorage.instance
.ref()
.child(path)
.putData(fileConverted)
.then((bla) => print("sucess"));
} on FirebaseException catch (e) {
return null;
}
}
The Firebase Storage SDKs can upload local data as either a File, an array of bytes, or a base-64 encoded string. The only URLs it accepts are so-called data URLs, which start with data:// and contain the complete data of the object. They cannot upload data directly from URLs that you more commonly see, such as http:// or https://.
You'll need to first download the data from that URL to the local device, and then upload it from there.

Upload CSV file Flutter Web

I am using the file_picker plugin to pick a CSV file in Flutter Web. Although I am able to pick the file it is converting the file into bytes (Uint8List). Is there any way I can get the original CSV file or if I can convert these bytes to CSV maybe I can get the path of the file?
Code:
void pickCSV() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['csv']);
if (result != null) {
var fileBytes = result.files.first.bytes;
csfFileName.value = result.files.first.name;
} else {
// User canceled the picker
}
}
I know it's a bit late but you have a couple of choices and maybe it helps others out aswell.
Both of the choices requires server-side processing, so you will need to read on how to do that.
Get the content of the CSV file send it to the server and make a new file on the server with that content. You can use String.fromCharCodes to read the content, in the web, after you select the file.
Convert the Uint8List into a base64 string, using base64Encode function, send it to the server, process it there.
Alternatively, if you use Firebase Storage you can use putData like so:
final metaData = SettableMetadata(contentType: mimeType);
final task = await _storage.ref().child(cloudPath).putData(fileData, metaData);
/// Get the URL
await task.ref.getDownloadURL()
Storing the mimeType ensures proper handling of the file when used after download
cloudPath means the location in FirebaseStorage, such as: storageDirectory/filename.extension
fileData is the Uint8List you provided

how to solve dynamic list type casting error in Hive?

sorry I am new in using Flutter and using Hive local storage.
I am using
hive: ^2.0.4
hive_flutter: ^1.0.0
I open the box in main function like this
Future<void> main() async {
await Hive.initFlutter();
await Hive.openBox<List<Event>>("events");
}
after getting the data from the server, I save all the events to hive by using code like this
final eventsBox = Hive.box<List<Event>>("events");
final List<Event> eventsFromServer = await getEventsFromServer();
eventsBox.put("recommended_events", eventsFromServer);
but I have error when trying to read the data from the box, I read it like this
final eventsBox = Hive.box<List<Event>>("events");
// error in this one line below
final eventsFromHive = eventsBox.get("recommended_events", defaultValue: []) ?? [];
type 'List < dynamic > ' is not a subtype of type 'List< Event >?' in type
cast
how to solve this type casting error?
from the documentation in here it is said
Lists returned by get() are always of type List (Maps of type
Map<dynamic, dynamic>). Use list.cast() to cast them to a
specific type.
I don't know if it is the solution of my problem or not, but I don't know how to implement that in my code.
I tried it like this, but I still have the same error
final eventsFromHive = eventsBox.get("recommended_events")!.cast<Event>();
or maybe the way I write the syntax to save and read the list are totally wrong? please help :)
Is not necessary to open your box as a List, because it is a box and can store many objects of the type that you declare, for example:
await Hive.openBox<MyModel>(boxName);
To get all the objects or data stored in that box, you can query like this:
final box = Hive.box<CompanyModel>(boxName);
List<CompanyModel> interviews = box.values.toList();
In addition, you have to create an Adapter Model if you want to store your own Model with Hive.
There is two dev dependencies to auto generate the Model:
dev_dependencies:
hive_generator:
build_runner:
Importing that dependencies and running this command flutter packages pub run build_runner build will generate the Model, but also you have to create your Model as the documentation indicates.
I suggest you to check out the documentation.
Hive - Generate Adapter
I can finally solve it by using it like this. in main function
Future<void> main() async {
await Hive.initFlutter();
await Hive.openBox("events");
}
when saving data list
final eventsBox = Hive.box("events");
eventsBox.put("recommended_events", eventsFromServer);
and read it like this
final eventsBox = Hive.box("events");
final eventsFromHive = eventsBox.get("recommended_events")?.cast<Event>() ?? [];
I have faced this kind of problem. It was absolutely the same. I do not know how you got kinda problem. Maybe it was the same with mine. I have just cleaned the box. and it has worked on me.
**Cause: **
I started it immediately after I made the box (for testing). he had taken the List<dynamic> object as it store. Once I made it clear, it stocked up data I had just given and it worked
Try:
boxName.clear() inside initState() and re-run it. if it will work do not forget to delete the line!
if you forget, it will clear the box every time.
Done with getting Hive as an List Object :)
Future<List<CustomModel>> getModels() async {
//box = await Hive.openBox<CustomModel>(Constants.Hive);
return box?.values.toList(growable: false)?.cast<CustomModel>() ?? <CustomModel>[];
}

Read an online text file and put it into a variable

I want to check an online txt file for the newest version code and show a dialog which says "Please update" or something similar. Is it posiible to put the content of the file into a variable?
EDIT: I tried Arpit Awasthi's solution but I get these errors:
lib/main.dart:685:25: Error: Method not found: 'HttpClient'.
var request = await HttpClient().getUrl(Uri.parse(url));
^^^^^^^^^^
lib/main.dart:687:23: Error: Method not found: 'consolidateHttpClientResponseBytes'.
var bytes = await consolidateHttpClientResponseBytes(response);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/main.dart:688:5: Error: 'Directory' isn't a type.
Directory appDocDir = await getApplicationDocumentsDirectory();
^^^^^^^^^
lib/main.dart:690:5: Error: 'File' isn't a type.
File file = File("${appDocDir.path}/$fileName");
^^^^
lib/main.dart:690:17: Error: Method not found: 'File'.
File file = File("${appDocDir.path}/$fileName");
^^^^
lib/main.dart:691:5: Error: 'File' isn't a type.
File urlFile = await file.writeAsBytes(bytes);
^^^^
You can use the following function to download the file and then get the File object of that file.
static downloadFile(String url) async{
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
Directory appDocDir = await getApplicationDocumentsDirectory();
String fileName = ('yourFileName.fileExtention');
File file = File("${appDocDir.path}/$fileName");
File urlFile = await file.writeAsBytes(bytes);
return urlFile;
}
Note :- I've used this plugin to get app folder path :- path_provider: ^1.6.18
Basically, what you can do is the following.
You May Define in a variable (context probably) you Current Version...
The you a async http request, you can call to an API where you check your latest release and if it is > that current one, trigger an alert dialog that shows that There is a new version available.

I have issues with the path on the getApplicationDocumentsDirectory() function

I get an error message over the path provider that says
error: The getter 'path' isn't defined for the class 'Future'.
I am trying to generate a PDF file following the https://pub.dev/packages/pdf#-example-tab- and this example https://github.com/javico2609/flutter-challenges/blob/master/lib/pages/code_examples/pdf_and_csv/pdf.dart
But as I go on I get the error that path isn't defined on the Future. But as I see on the web I am doing it right. Here is the code:
final String dir = (getApplicationDocumentsDirectory()).path;
final String path = '$dir/receta.pdf';
final File file = File(path);
file.writeAsBytesSync(newpdf.save());
As I said. I can't run the app because I get the message error: The getter 'path' isn't defined for the class 'Future'.
Also tried to write
final Future<Directory> directory = getApplicationDocumentsDirectory();
final String dir = directory.path;
final String path = '$dir/receta.pdf';
final File file = File(path);
file.writeAsBytesSync(newpdf.save());
But it doesn't work, path on the variable dir shows the error
In final Future<Directory> directory = getApplicationDocumentsDirectory(); getApplicationDocumentsDirectory() is any async function which means it will return the directory asynchronously , So then when you are trying to read directory.path;, directory is not initialized yet, its null.
Instead returning a future directory wait till it is initialized,
final Directory directory = await getApplicationDocumentsDirectory();
Import this.. it solves the issue
import 'package:path_provider/path_provider.dart';
You must put await keyword like this:
final directory = await getApplicationDocumentsDirectory();
final path = join(directory.path, 'db_todolist_sqflite');