following is my code -
abc.js
class abc {
async foo1() {
// do something
return result;
}
async foo2() {
// do something
return result;
}
module.exports = abc
}
another-file.js
const abc = requir(./abc);
abc.foo1();
// this results in error
// TypeError : abc.foo1 is not a function
How should I do this?
Several points. By convention class names starts with capital letter. Your problem has nothing to do with async functions. You have 2 options to solve this problem. First option is to make your function static. Then you can use it directly without instance. Second option is just call it differently: instantiate class first to get instance, and then call your method on this instance.
And also keep in mind, that await keyword can be used only inside other async function. And you need await keyword if you want to handle promise, returned by async function (it returns promise of result, not result)
Related
I am making a function in nodejs to read a value from the database in Firebase and return it. I read in the that way and get the right value by the console.log(), but when i made the return of the value doesn´t work properly when i call that function
function test() {
database.ref(sessionId + '/name/').once("value").then((snapshot) => {
var name = snapshot.child("respuesta").val()
console.log(name);
return name;
});
}
If someone could help me. Thanks
You're not returning anything from test, so undefined is being implicitly returned. You can return the promise like this:
function test() {
return database.ref(// everything else is identical
}
Note that this will be returning a promise that resolves to the name, not the name itself. It's impossible to return the name, because that doesn't exist yet. To interact with the eventual value of the promise, you can call .then on the promise:
test().then(name => {
// Put your code that uses the name here
})
Or you can put your code in an async function and await the promise:
async function someFunction() {
const name = await test();
// Put your code that uses the name here
}
Here is my code in TypeScript:
private getInfoSystem = () => {
this.systemInfo = {
cpuSpeed: 0 ,
totalRam: os.totalmem(),
freeRam: os.freemem(),
sysUpTime: os_utils.sysUptime(),
loadAvgMinutes: {
one: os_utils.loadavg(1),
five: os_utils.loadavg(5),
fifteen: os_utils.loadavg(15),
}
}
si.cpuCurrentSpeed().then ((data)=> {
this.systemInfo.cpuSpeed = data.avg ;
});
return this.systemInfo;
};
The property "cpuSpeed" first initialized to Zero and then I call the method cpuCurrentSpeed() which use a callback function and I try to put the value in "cpuSpeed".
The problem is that the the data of cpuCurrentSpeed() is late and the return value not include the wanted value in "cpuSpeed".
Because you are using .then on the cpuCurrentSpeed call, I assume that it's returning a Promise and not using callbacks. If it's like this, you could make your method asynchronous and await it:
private getInfoSystem = async () => {
this.systemInfo = {
cpuSpeed: 0 ,
totalRam: os.totalmem(),
freeRam: os.freemem(),
sysUpTime: os_utils.sysUptime(),
loadAvgMinutes: {
one: os_utils.loadavg(1),
five: os_utils.loadavg(5),
fifteen: os_utils.loadavg(15),
}
}
this.systemInfo.cpuSpeed = (await si.cpuCurrentSpeed()).avg;
return this.systemInfo;
};
Please note, that in this case your method also returns a Promise of the type of the value of this.systemInfo afterwards (which then needs to be awaited again by the calling method).
Otherwise, you can only rely on the returning value of Promises or callbacks inside of the callback because of it's asynchronous nature.
the console.log(workingWeekdaysVar) line; is outside the findOne's scope, and the variable was declared outside it too, yet it's giving me null ...
when i put console.log(workingWeekdaysVar); inside the findOne's scope, it does give the right output, but this is useless for me because I wanna use workingWeekdaysVar elsewhere below.
The two commented out lines are the 2nd approach i attempted to do, but it gave me an undesirable output because this whole code is inside a complicated for loop.
How can I simply pass the fetched value of workingWeekdaysVar out of the scope?
var workingWeekdaysVar = [];
buyerSupplierFisModel.findOne(filter).then(function (combo) {
workingWeekdaysVar = combo.workingWeekdays;
//server.getWorkingWeekdays = function () { return combo.workingWeekdays };
});
console.log(workingWeekdaysVar);
//console.log(server.getWorkingWeekdays());
findOne() is an asynchronous function (it returns a promise object). This means that it returns inmediately and your next code line is run (in this case, console.log(workingWeekdaysVar);. But, since the function isn't done yet, workingWeekdaysVar is empty, and it will be empty until findOne() has done its job and returned the results in the provided chained callback .then(function (combo) {....
So if you want to do anything with the results, you'll have to do it in the callback. One option to this would be to use async / await:
(async () => {
try {
const { workingWeekdaysVar } = await buyerSupplierFisModel.findOne(filter)
console.log(workingWeekdaysVar)
} catch (e) {
console.log(`Error: ${e}`);
}
})()
Re-arranging your code a bit:
let doToResponse = (combo)=>{
workingWeekdaysVar = combo.workingWeekdays;
console.log(workingWeekdaysVar);
}
buyerSupplierFisModel.findOne(filter).then(function (combo) {
doToResponse(combo)
});
good for re-usability
My personal favorite:
buyerSupplierFisModel.findOne(filter).then(combo=> {
workingWeekdaysVar = combo.workingWeekdays;
console.log(workingWeekdaysVar);
});
The important thing is keep in mind, as Miguel Calderón says.. findOne - returns a promise. At that point you have another thread with different local (Lexical?) scope
I have a function,
asdf() {
var a = fooController.getOrCreateFooByBar(param);
console.log("tryna do thing");
console.log(a); //undefined
if (!a.property) {
//blah
}
that dies. getOrCreateFooByBar does a
Model.find({phoneNumber : number}).exec()
.then(function(users) {})
and finds or creates the model, returning it at the end:
.then(function(foo) { return foo}
How can I use the result of this in asdf()? I feel like this is a fairly easy question but I am getting stuck. If I try to do a.exec() or a.then() I get 'a cannot read property of undefined' error.
The main idea about Promises (as opposed to passed callbacks) is that they are actual objects you can pass around and return.
fooController.getOrCreateFooByBar would need to return the Promise it gets from Model.find() (after all of the processing done on it). Then, you'll be able to access it in a in your asdf function.
In turn, asdf() should also return a Promise, which would make asdf() thenable as well. As long as you keep returning Promises from asynchronous functions, you can keep chaining them.
// mock, you should use the real one
const Model = { find() { return Promise.resolve('foo'); } };
function badExample() {
Model.find().then(value => doStuff(value));
}
function goodExample() {
return Model.find().then(value => doStuff(value));
}
function asdf() {
var a = badExample();
var b = goodExample();
// a.then(whatever); // error, a is undefined because badExample doesn't return anything
return b.then(whatever); // works, and asdf can be chained because it returns a promise!
}
asdf().then(valueAfterWhatever => doStuff(valueAfterWhatever));
i have a question regarding defining objects in modules.
lets say i have a module:
/*---obj----*/
function A (param){
this.parm=param;
function func(){
//do somthing
}
}
exports.func=func;
/*---file.js----*/
obj=require('obj');
function fileFunc(A){
A.func();//with out this line it works fine
A.param=2;
}
}
for some reason it does not recognize the function in the object A. it recognizes the object A and its different vars, but when it comes to executing the function it gives the msg:
TypeError: Object # has no method 'func'
i tried also to export the function in A by:
exports.A.func=A.func
or
exports.func=func
neither works..
does someone have a clue?
thanx
matti
The function you defined inside of A is local only to that function. What you want is
function A(param) {
this.param = param;
}
A.func = function() {
// do something
};
But if you are treating A as a constructor then you'll want to put that function in A's prototype
A.prototype.func = function() {
// do something
};