Having this code:
const fs = require('fs')
const file = 'books.json';
class Book{
constructor(code) {
this._code = code;
}
get code() {
return this._code;
}
set code(value) {
this._code = value;
}
}
async function writeBooks(){
const data = JSON.stringify([new Book('c1'), new Book('c2')]);
await fs.promises.writeFile(file, data, 'utf8');
}
async function getBook(code){
try{
const data = await fs.promises.readFile(file);
const array = JSON.parse(data);
return array.find(b => b.code === code);
} catch (err){
console.log(err)
}
}
writeBooks();
getBook('c1').then(b => console.log(b));
I am getting undefined
(instead of the expecting book object).
How to get the object (the above problem)
If
async
function always returns promise, how can I then return object for the client, instead of him having to callthen()
from thegetBook(code)
?do I need to
await
for thefs.promises.writeFile()
? as I am doing inwriteBooks()
? As fas as I understand theasync/await
now, is that the return value fromawait
function is the data or error. But since thewriteFile()
does not returns anything, or error at most (as opposed toreadFile()
) why would I want toawait
for no data?
CodePudding user response:
Actually the root of problem is not about async/awaits or promises. The problem is trying to write an array to a json file. If you write your json data like the code snippet below (as a key-value pair), your problem is solved.
{"1": [new Book('c1').code, new Book('c2').code]} //as a key-value pair
const fs = require('fs')
const file = 'books.json';
class Book{
constructor(code) {
this._code = code;
}
get code() {
return this._code;
}
set code(value) {
this._code = value;
}
}
async function writeBooks(){
const data = JSON.stringify({"1": [new Book('c1').code, new Book('c2').code]});
await fs.promises.writeFile(file, data, 'utf8');
}
async function getBook(code){
try{
const data = await fs.promises.readFile(file);
const dataOnJsonFile = JSON.parse(data);
return dataOnJsonFile["1"];
} catch (err){
console.log(err)
}
}
writeBooks();
getBook('c1').then(b => console.log(b));
CodePudding user response:
The above problem is that the Books returned from
JSON.parse
have only data, not methods, and thus I cannot get thecode
viaget code(){}
, but only as public parameter of classBook
asbook._code
, which however breaks encapsulation (convetion is that_[propery]
is private, and there should be appropriate getters/setters). So I made the properties public (and broke encapsulation), because I still don't know, how to assign methods to object created from JSON.No, the result of
async
is always Promise. You cannot unwrap it insideasync
, the client will always have to unwrap it. (soawait fs.promises.WriteFile()
will unwrap it, but then immediately wrap it back, before async function returns.as explained above.