Calling other functions of a class inside a Promise in Node - javascript

So, I have two methods in a class. Both returns a promise. The second function calls the first function from inside of the promise it returns.
module.exports = {
funcA: () => {
return new Promise((resolve, reject) => {
something ? resolve(something): reject('nope');
});
}
funcB: () => {
return new Promise(async(resolve, reject) => {
try {
const something = await this.funcA();
} catch(err) {
reject('error');
}
}
}
When I am trying to call funcB() from another class, like this:
let something = await someService.funcB();
I am getting:
TypeError: this.funcA() is not a function
Can you shed some light on why this is happening and how to solve this problem?

one way to make it work is to create the function outside of the module.exports block to get a reference of each function. Then this keyword can be omitted
const funcA = () => {
return new Promise((resolve, reject) => {
// code here
});
};
const funcB = () => {
return new Promise(async(resolve, reject) => {
try {
const something = await funcA();
resolve(something);
} catch(err) {
reject('error');
}
})
};
module.exports = {
funcA,
funcB
}

I think this is what you need to do
module.exports = {
funcA: function() {
return new Promise((resolve, reject) => {
something ? resolve(something): reject('nope');
});
}
funcB: function() {
return new Promise(async(resolve, reject) => {
try {
const something = await this.funcA();
} catch(err) {
reject('error');
}
}
}
I've found using arrow functions inside objects as you've done breaks this, but you can fix it this way.

Related

SyntaxError: await is only valid in async function. Unable to Correct it

I am unable to run the following code.
It shows me this error:
SyntaxError: await is only valid in async function
const Prom = async() => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = await Prom();
console.log(final);
You could use IIFE
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2
if (a == 2) {
resolve('Its working')
} else {
reject('Its not working')
}
})
}
;(async function() {
const final = await Prom()
console.log(final)
})()
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = async () => {
const result = await Prom();
console.log(result);
};
final();
await can only be used inside an async function.
The error here is referring to the final variable. It has to be inside of an async function. Try using the below code.
const prom = new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
(async function() {
const final = await prom;
console.log(final)
})()

Resolve promise after callback it's executed

I have the following code on which I am trying to block the execution of the method _saveAddress multiple time, so I made a promise for this method.
const [pressEventDisabled, setPressEventDisabled] = useState(false);
<TouchableOpacity style={style.button_container} activeOpacity={1} disabled={pressEventDisabled} onPress={async () => {setPressEventDisabled(true); await _saveAddress(); setPressEventDisabled(false);}} >
The problem is that I want to resolve the promise after the callback method it's executed. It's there any way to wait for the dispatch function to execute or to resolve the promise inside the callback method?
This is the method for saving the address:
const _saveAddress = () => new Promise(async (resolve) => {
var valid = _validate();
if (valid) {
const address = createAddressJson();
if (addressId) {
var addressIdProperty = {
id: addressId
};
const newAddress = Object.assign(addressIdProperty, address);
dispatch(editAddress(newAddress, _onAddressSaveEditCallback));
} else {
dispatch(addAddress(address, _onAddressSaveEditCallback));
}
} else {
//notify
notifyMessage(strings.fill_required_inputs_validation);
resolve();
}
});
This is the callback method:
const _onAddressSaveEditCallback = async (success: boolean, apiValidations: any, address ? : Address, ) => {
if (success) {
if (typeof callback == 'function') {
callback(address);
}
await Navigation.pop(componentId);
} else {
setDataValidations(apiValidations);
}
};
Just do exactly what you say in the title. Nothing more, nothing less:
if (addressId) {
var addressIdProperty = {id: addressId};
const newAddress = Object.assign(addressIdProperty, address);
dispatch(editAddress(newAddress, async (s,v,a) => {
await _onAddressSaveEditCallback(s,v,a);
resolve();
}));
} else {
dispatch(addAddress(address, async (s,v,a) => {
await _onAddressSaveEditCallback(s,v,a);
resolve();
}));
}
Of course, since you are passing async () => {} to addAddress instead of _onAddressSaveEditCallback you have to call _onAddressSaveEditCallback yourself since addAddress will be calling the async () => ...
But mixing promises and callbacks like this isn't great. It leads to weird looking and sometimes confusing code. A better solution is to promisify addAddress:
function addAddressPromise (address) {
return new Promise((resolve, reject) => {
addAddress(address, (success, validations, address) {
if (success) return resolve(address);
else reject(validations)
});
});
}
Now you can wait for addAddress:
const _saveAddress = async () => {
// Don't create new promise here, we do it in addAddress..
// ...
let result = await addAddressPromise(address);
dispatch(result);
await _onAddressSaveEditCallback();
// ...
}

React call export function in same file

I'm new to React!
I have a function...
export const getBookingData = () => dispatch => {
console.log('ran getBookingData');
return new Promise(async (resolve, reject) => {
})
}
Which I then call in another file by doing (which works fine):
import { getBookingData } from "../actions";
getBookingData(); // logs 'ran getBookingData'
However, I would like to try and call getBookingData from within the same file that it is declared.
I have tried:
const getBookingData = () => dispatch => {
console.log('ran getBookingData');
return new Promise(async (resolve, reject) => {
})
}
const moveVisitor = (visitorId, destination, source) => async (dispatch, getState) => {
console.log('error with post api'); // logs ok
getBookingData(); // doesn't log 'ran getBookingData'
let state = getState();
let { entities: { booking: { booking_id } } } = state;
let removeBed = {};
removeBed.booking_visitor_name_id = visitorId;
removeBed.room_id = destination;
removeBed.booking_id = booking_id;
api.post('/accommodation/room/move-participant', removeBed).then(function (response) {
// ok
}).catch(function (error) {
});
}
export { getBookingData, moveVisitor }
You can say that the getBookingData function is curried, as it is a function (accepting no parameter) returning another function (accepting dispatch object as parameter). What you have by just calling getBookingData() is an anonymous function which accepts the dispatch object as the parameter, so you need to call it once more.
Replacing your non-working call of getBookingData() with getBookingData()(dispatch) should work.
Have you tried exporting as below
const getBookingData = () => dispatch => {
return new Promise(async (resolve, reject) => {
// some stuff here
})
}
const moveVisitor = (visitorId, destination, source) => async (dispatch, getState) => {
getBookingData(); // doesn't work
}
export { getBookingData, moveVisitor }

Writing to file in a promise

The function here creates a bunch of files but does not write to them. How ever, if I remove the Promise.all in the end and don't resolve the function at all it DOES write the data to the files. It doesn't matter what I try to write, I can comment out everything and just write 'hello world' and it still won't write anything. The question is simple, why?
const writeSmilFiles = (smilInfo) => {
return new Promise ((resolve, reject) => {
const p1 = smilPartOne();
const p2 = smilPartTwo();
let promises = dataTypes.new.camera_set.map(instance => {
return new Promise((resolve, reject) => {
const smilEntries = smilInfo.filter(smil => smil.BroadcastAndKlippTupleId == instance.BroadcastAndKlippTupleId && smil.CameraId == instance.CameraId);
try {
const fileName = `${__dirname}/newSmilFiles/${smilEntries[0].Smil}`;
const file = fs.createWriteStream(fileName);
file.write(p1);
smilEntries.forEach(entry => {
const smilEntry = smilSwitch(entry.Filename, entry.Bitrate, entry.Width, entry.Height);
file.write(smilEntry);
console.log(smilEntry);
file.write('\n');
});
file.write(p2);
file.end();
resolve(`Smil written.`);
} catch (ex) {
reject(ex);
}
});
});
Promise.all(promises).then(msg => {
resolve(msg);
});
});
};
Resolve when the stream has actually finished:
file.on("finish", () => resolve(`Smil written.`));

ES2015 equivalent of $.Deferred()

I'm using Babel for a project, and I'm stuck with a very basic problem. I'm very used to jQuery's Deferred objects and I'm struggling to find its ES2015 equivalent, here is what I basically want:
// file1.js
let dfd = new Promise()
function functionCalledAtSomePoint(thing) {
dfd.resolve(thing)
}
export default { dfd }
// file2.js
import { dfd } from './file1'
dfd.then((thing) => {
console.log('Yay thing:', thing)
})
What should be the correct way to write this simple deferred?
EDIT with royhowie's answer:
// file1.js
let thing
function getThing(_thing) {
return new Promise((resolve) => {
if (el) {
thing = new Thing(el)
}
resolve(thing)
})
}
function functionCalledAtSomePoint(el) {
getThing(el)
}
export default { getThing }
// file2.js
import { getThing } from './file1'
getThing.then((thing) => {
console.log('Yay thing:', thing)
})
You can export the promise directly (instead of a function)—like you have—but then you'll only be able to use it (.then) once, which is probably not what you want.
Instead, you should export a function which returns a Promise:
file 1.js
import User from '../models/user'
export function getUsersFromDatabase () {
return new Promise((resolve, reject) => {
User.find({}, (err, users) => {
return err ? reject(err) : resolve(users)
})
})
}
file2.js
import { getUsersFromDatabase } from './file1'
getUsersFromDatabase().then((users) => {
// success
}).catch((err) => {
// no users
})
You can use the default Promise implementation, but it much slower than 3rd party modules, e.g., bluebird (which I very much recommend using).
I'm very used to jQuery's Deferred objects and I'm struggling to find its ES2015 equivalent
If you must use deferred, this should work
function makeDeferred() {
var res, rej;
let dfd = new Promise(function(resolve, reject) {
res = resolve;
rej = reject;
});
dfd.resolve = res;
dfd.reject = rej;
return dfd;
}
let dfd = makeDeferred();
However, rewriting your code to avoid such kludge would be preferable (but not unavoidable - I still have one piece of code I can't get rid of the deferred promise in, so I feel your pain
This class will allow you to use the regular Promise methods as well as an additional resolve(value) method. This should give you a similar functionality as jQuery.deferred().
function DeferredPromise() {
var _resolve = null;
var _reject = null;
this.promise = new Promise(function(resolve, reject) {
_resolve = resolve;
_reject = reject;
});
this.then = function() {
return this.promise.then(...arguments);
}
this.catch = function() {
return this.promise.catch(...arguments);
}
this.resolve = function() {
_resolve(...arguments);
}
this.reject = function() {
_reject(...arguments);
}
}
Then you can use it to create a new DeferredPromise:
var p = new DeferredPromise();
Wait for it:
p.then(val => {
console.log('val(1)', val);
})
Maybe wait for it another time, you can also chain it with a regular Promise:
p.then(val => {
console.log('val(2)', val);
return 42;
}).then(val => {
console.log('.then(somethingElse)', val);
})
.catch(err => { console.error('err', err); })
And resolve it whenever you want:
p.resolve({ username: 'Luke.Skywalker', age: 42 });

Categories

Resources