Get text from ".txt" file and save it in String variable dart - string

I have a ".txt" file called "bio.txt" inside the Document folder of my application.
I want to read its content and store it inside a String variable.
My problem is that the "reading action" is a "Future" function and I have some troubles to save its value in a "String".
I read the file with :
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> _localFile(String name) async {
final path = await _localPath;
return File('$path/$name');
}
Future<String> _read(String filename) async {
try {
final file = await _localFile(filename);
// Read the file.
return await file.readAsString();
} catch (e) {
// If encountering an error, return 0.
return "Can't read";
}
}
And I would like to save it with :
String _bio = _read("bio.txt").then((value) => String);
Do you know why this solution isn't working?
Any suggestion?

Because the then of Futures won't return a value, it should be like this,
var _bio;
_read("bio.txt").then((value) {
_bio = value;
});
or by making the context _bio is in to an asynchronous one,
var _bio = await _read("bio.txt");

You can either use a then block or use the async/await
_read ('file.txt').then((value){
bio = value;
});
Or:
bio = await _read ('file.txt');

This is my solution :
String _myRead( String filename){
var _bio;
_read("bio.txt").then((String) {
_bio = String;
});
return _bio;
}
String _bio=_myRead("bio.txt");

Related

Value returning from an async function is not the actual value

I'm calling an async function that has the file path as a parameter and reads and displays the content in the file.
this is the place where I'm invoking the function.
this is the function.
After reading the contents in the file, the data is printed in the console.
But when I try to use the same value to display in the emulator I'm getting error.
Why actual string value is not returned from the function??
error.
readContent is a future method, you need to wait to complete the fetching.
For future method, try using FutureBuilder.
late Future future = readContent();
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("${snapshot.data}");
}
return CircularProgressIndicator();
},
),
);
}
Find more about using FutureBuilder.
An async function in dart can only return a Future.
Your readContent function signature doesn't declare a return value:
readContent(String path) async {
var result = await File(path).readAsString();
print(result);
return result
}
If you explicitly declare the return value as String you'll get a compilation error. Async methods can only return a future:
Future<String> readContent(String path) async {
var result = await File(path).readAsString();
print(result);
return result
}
The await keyword allows you to access the value returned by a Future, it is not the same as calling the function synchronously.
The only reason you need the await keyword in your code is because you're printing the value to console when the Future completes. You could do this instead, which is the same function without printing to console and without async await.
readContent(String path) {
return File(path).readAsString();
}
To address the issue described in your question, you might call readAsString synchronously:
readContent(String path) {
return File(path).readAsStringSync();
}
Or use await on the calling side
var val = await readContent(path);
Or
var txt = "";
readContent(path).then((value) {
txt = value;
setState(() {});
});
Or use the FutureBuilder widget

nodejs function().anotherFunction() how they do it?

I install a library/module but I am curious how they do it
const modules = require('abc');
const app = new modules('123');
const client = app.f1('abcdef').f2('ghi');
console.log(client.to());
const client2 = app.f1('1111111').f2('2222');
console.log(client2.to());
console.log(client.to());
result is 123:abcdef-ghi
result is 123:1111111-2222
result is 123:abcdef-ghi
how they did it?
i want to create that example lib/module
please give me sample code
Depending on your exact requirements, something like this seems to work:
let state = Symbol("private")
class App {
constructor(arg) {
this[state] = arg
}
f1 = arg => new App(this[state] + ":" + arg)
f2 = arg => new App(this[state] + "-" + arg)
to = () => this[state]
}
Here each of the chainable method returns a new instance of the class, each keeping the temporary result as a local state. The to() method returns that state.
This is what I use for doing function().anotherFunction()
function func() {
console.log("ran func")
return {
"anotherFunc": function () {
console.log("ran another func")
}
}
}
func().anotherFunc()
You can also just return a object
const returnData = {
"anotherFunc": function () {
console.log("ran another func")
}
}
function func() {
console.log("ran func")
return returnData
}
func().anotherFunc()
Example of use:
function word1(in_1) {
return {
"word2": function (in_2) {
console.log(`Inputs: ${in_1} ${in_2}`)
}
}
}
word1("Hello").word2("World")
// Expected output: Inputs: Hello World

Return String from Future Object

I am trying to fetch html page via localproxy to parse and get urls from it. I can't find any library which works without Future in Dart. So i have difficulty returning String from a Future Object. Below is full code of dart file.
import 'package:universal_html/driver.dart';
import 'package:universal_html/prefer_universal/html.dart';
String proxyUrl='http://localhost/php-proxy/index.php?q=';
String hallTicketUrl='http://www.ignou.ac.in/ignou/studentzone/results/6';
Future<String> getList()async{
final driver = HtmlDriver();
await driver.setDocumentFromUri(Uri.parse(proxyUrl+hallTicketUrl));
final items = driver.document.querySelectorAll('.middleconten2column a');
Element urls=Element.tag('urls');
items.forEach((item)=>urls.append(Element.tag('url')
..setAttribute('href',item.getAttribute('href'))
..text=item.text
)
);
print('${items.length} items found');
return Future.value(urls.outerHtml);
}
String Handler(String app){
switch(app){
case 'list': return getList() as String;
}
return "";
}
main(){
print(Handler('list'));
}
I think you have misunderstood what the async keyword does to methods. When a method are marked as async it will always automatically returns a Future of something. That is the reason why you need to specify e.g. Future<String> as the return type.
But because the creation are done "automatically" you don't really need to do the following:
return Future.value(urls.outerHtml);
But can just do:
return urls.outerHtml;
After this your have discovered the problem with using asynchronous programming where everything in your call stack needs to be marked as async since you have an await somewhere in your code.
I have fixed your code so it now hope it works correctly with all the future stuff:
import 'package:universal_html/driver.dart';
import 'package:universal_html/prefer_universal/html.dart';
String proxyUrl = 'http://localhost/php-proxy/index.php?q=';
String hallTicketUrl = 'http://www.ignou.ac.in/ignou/studentzone/results/6';
Future<String> getList() async {
final driver = HtmlDriver();
await driver.setDocumentFromUri(Uri.parse(proxyUrl + hallTicketUrl));
final items = driver.document.querySelectorAll('.middleconten2column a');
Element urls = Element.tag('urls');
items.forEach((item) => urls.append(Element.tag('url')
..setAttribute('href', item.getAttribute('href'))
..text = item.text));
print('${items.length} items found');
return urls.outerHtml;
}
Future<String> Handler(String app) async {
switch (app) {
case 'list':
return await getList();
}
return "";
}
main() async {
print(await Handler('list'));
}

Unable to use variable outside of class in the class

I am making a simple note taking app to learn node and ES6. I have 3 modules - App, NotesManager and Note. I am importing the Note class into the NotesManager and am trying to instantiate it in its addNote function. The problem is that even though the import is correct, it turns out to be undefined inside the class definition. A simpler solution would be to just instantiate the NotesManager class and add the Note class to its constructor however, I want to have NotesManager as a static utility class.
Here is my code.
Note.js
class Note {
constructor(title, body) {
this.title = title;
this.body = body;
}
}
module.exports = Note;
NotesManager.js
const note = require("./Note");
console.log("Note: ", note); //shows correctly
class NotesManager {
constructor() {}
static addNote(title, body) {
const note = new note(title, body); //Fails here as note is undefined
NotesManager.notes.push(note);
}
static getNote(title) {
if (title) {
console.log(`Getting Note: ${title}`);
} else {
console.log("Please provide a legit title");
}
}
static removeNote(title) {
if (title) {
console.log(`Removing Note: ${title}`);
} else {
console.log("Please provide a legit title");
}
}
static getAll() {
//console.log("Getting all notes ", NotesManager.notes, note);
}
}
NotesManager.notes = []; //Want notes to be a static variable
module.exports.NotesManager = NotesManager;
App.js
console.log("Starting App");
const fs = require("fs"),
_ = require("lodash"),
yargs = require("yargs"),
{ NotesManager } = require("./NotesManager");
console.log(NotesManager.getAll()); //works
const command = process.argv[2],
argv = yargs.argv;
console.log(argv);
switch (command) {
case "add":
const title = argv.title || "No title given";
const body = argv.body || "";
NotesManager.addNote(title, body); //Fails here
break;
case "list":
NotesManager.getAll();
break;
case "remove":
NotesManager.removeNote(argv.title);
break;
case "read":
NotesManager.getNote(argv.title);
break;
default:
notes.getAll();
break;
}
Is it possible for me to create a strict utility class which I can use without instantiating like in Java? Pretty new here and have tried searching for it without any luck. Thank you for your help.
When you do this:
const note = new note(title, body);
you redefine note shadowing the original note from the outer scope. You need to pick a different variable name.
Something like this should work better:
static addNote(title, body) {
const some_note = new note(title, body); //Fails here as note is undefined
NotesManager.notes.push(some_note);
}

Firebase startAfter is not working for doc ref

Docs I am following: https://firebase.google.com/docs/firestore/query-data/query-cursors
I have code like below;
async List(query: any): Promise<Array<any>> {
let collectionQuery = super.GetCollectionReference();
if (query.VideoChannelId) {
collectionQuery = collectionQuery.where(
"VideoChannel.Id",
"==",
query.VideoChannelId
);
}
let startAfterDoc: any = "";
if (query.StartAfter) {
startAfterDoc = await super.GetDocumentReference(query.StartAfter);
}
collectionQuery = collectionQuery
.orderBy(query.OrderBy, "desc")
.startAfter(startAfterDoc)
.limit(query.Limit);
let items = await super.List(collectionQuery);
return items;
}
And utility methods:
GetDocumentReference(id: string): any {
return this.GetCollectionReference().doc(id);
}
async GetDocumentSnapshot(id: string): Promise<any> {
return await this.GetDocumentReference(id).get();
}
GetCollectionReference(): any {
return this.db.collection(this.CollectionName);
}
Regardless what ever value I pass for query.StartAfter it always returns top document in the collection.
I am pretty sure document exists with id query.StartAfter.
If I use GetDocumentSnapshot instead of GetCollectionReference, then I am getting parse error at firebase API.
Indexes has been added for query.OrderBy (CreateDate) and Id fields.
What possibly I would be missing here?

Resources