Async function returning existing array as undefined - javascript

I have an async function inside my class that does execute like it is supposed, but its return value is undefined when I call it. Executing console.log(array) just before the return line "return array" does work
I've tried setting up the variable in this.array but it is not working either.
class Core {
constructor(key) {
this.key = key;
}
async getSessions() {
var finalresponse = []
try {
// wait for response
await fetch("https://api.purecore.io/rest/1/session/get/?key=" + this.key, { method: "GET" }).then(function (response) {
return response.json();
}).then(function (jsonresponse) {
// looks for errors
if (jsonresponse.error != null) {
throw new Error("PureCore returned an error: " + jsonresponse.error + " -> " + jsonresponse.msg)
} else {
// adds the sessions to the response
jsonresponse.forEach(player => {
finalresponse.push(new CoreSession(player["mojang_username"], player["mojang_uuid"], player["core_id"], player["verified"]))
});
console.log(finalresponse) // returns array list
return finalresponse; // returns undefined
}
});
} catch (e) {
throw new Error("Error while getting the response for 'https://api.purecore.io/rest/1/session/get/?key=" + this.key + "' -> " + e.message)
}
}
}
class CoreSession {
constructor(username, uuid, core_uuid, verified) {
this.username = username;
this.uuid = uuid;
this.core_uuid = core_uuid;
this.verified = verified;
}
}
// testing:
sessions = new Core("731b59d106ea5acd0a385958d8e0f18b4b74b741f28f6efa43ed4a273a42d6f9").getSessions().then(function (value) {
console.log(value)
}, function (reason) {
console.log(reason)
});
I'm getting these results:
(from the chrome debug tool)

you have to return something from the async function,
// wait for response
return await fetch("https://api.purecore.io/rest/1/session/get/?key=" + this.key, { method: "GET" }).then(function (response) {
class Core {
constructor(key) {
this.key = key;
}
async getSessions() {
var finalresponse = []
try {
// wait for response
return await fetch("https://api.purecore.io/rest/1/session/get/?key=" + this.key, { method: "GET" }).then(function (response) {
return response.json();
}).then(function (jsonresponse) {
// looks for errors
if (jsonresponse.error != null) {
throw new Error("PureCore returned an error: " + jsonresponse.error + " -> " + jsonresponse.msg)
} else {
// adds the sessions to the response
jsonresponse.forEach(player => {
finalresponse.push(new CoreSession(player["mojang_username"], player["mojang_uuid"], player["core_id"], player["verified"]))
});
console.log(finalresponse) // returns array list
return finalresponse; // returns undefined
}
});
} catch (e) {
throw new Error("Error while getting the response for 'https://api.purecore.io/rest/1/session/get/?key=" + this.key + "' -> " + e.message)
}
}
}
class CoreSession {
constructor(username, uuid, core_uuid, verified) {
this.username = username;
this.uuid = uuid;
this.core_uuid = core_uuid;
this.verified = verified;
}
}
// testing:
sessions = new Core("731b59d106ea5acd0a385958d8e0f18b4b74b741f28f6efa43ed4a273a42d6f9").getSessions().then(function (value) {
console.log(value)
}, function (reason) {
console.log(reason)
});

Related

how to handle exception for promise in loop?

I am downloading files with zip folder, but it download the zip folder prior to add files in the zip folder object. If I remove them and catch block from call of "this. UrlToPromise ()" it works right, but when it faced reject from "this. UrlToPromise ()" it does not work correctly.
var zip = new JSZip();
zip = this.makezip(files, zip);
zip.generateAsync({ type: "blob" }).then(function (content) {
if (downloadName) {
console.log('zip download one', zip);
FileSaver.saveAs(content, downloadName + '.zip');
} else {
FileSaver.saveAs(content, 'All.zip');
}
});
async makezip(files, zip, folderName = null) {
if (folderName)
var tempFolder = zip.folder(folderName);
for (var i in files) {
files[i].hasOwnProperty('file_title')
if (!Array.isArray(files[i])) {
if (typeof files[i]['file_title'] !== 'undefined' && typeof files[i]['file_path'] !== 'undefined') {
await this.urlToPromise(files[i]['file_path']).then(response=>{
if (!folderName)
zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
else
tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
})
}
} else if (Array.isArray(files[i])) {
zip = this.makezip(files[i], zip, i);
}
}
return zip;
}
urlToPromise(url) {
return new Promise(function (resolve, reject) {
JSZipUtils.getBinaryContent(url, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
Whenever you use reject in a Promise constructor it will trigger the catch method of the Promise instance. Therefore, you need to add a catch handler when you call urlToPromise, like this:
this.urlToPromise(files[i]['file_path']).then(response=>{
if (!folderName)
zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
else
tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
}).catch(error => {
// do something with the error
})
Use await inside async function instead of then/catch. You can use try catch statement to catch the error.
async makezip(files, zip, folderName = null) {
if (folderName) var tempFolder = zip.folder(folderName);
for (var i in files) {
files[i].hasOwnProperty('file_title');
if (!Array.isArray(files[i])) {
if (
typeof files[i]['file_title'] !== 'undefined' &&
typeof files[i]['file_path'] !== 'undefined'
) {
try {
const response = await this.urlToPromise(files[i]['file_path']);
if (!folderName)
zip.file(
files[i]['file_title'] +
'.' +
returnExtFromImage(files[i]['file_path']),
response,
{ base64: true, binary: true }
);
else
tempFolder.file(
files[i]['file_title'] +
'.' +
returnExtFromImage(files[i]['file_path']),
response,
{ base64: true, binary: true }
);
} catch (error) {
// handle error
}
}
} else if (Array.isArray(files[i])) {
zip = this.makezip(files[i], zip, i);
}
}
return zip;
}
I am answering my own question i was missing await for recursive function.
var zip = new JSZip();
await this.makezip(files, zip).then(zip=>{
zip.generateAsync({ type: "blob" }).then(function (content) {
if (downloadName) {
FileSaver.saveAs(content, downloadName + '.zip');
} else {
FileSaver.saveAs(content, 'All.zip');
}
});
});
async makezip(files, zip, folderName = null) {
/*if folder name exist in props to create new nested folders*/
if (folderName)
var tempFolder = zip.folder(folderName);
for (var i in files) {
files[i].hasOwnProperty('file_title')
if (!Array.isArray(files[i])) {
if (typeof files[i]['file_title'] !== 'undefined' && typeof files[i]['file_path'] !== 'undefined') {
await this.urlToPromise(files[i]['file_path']).then(response=>{
if (!folderName)
zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
else
tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
}).catch(err=>{
});
}
}
else if (Array.isArray(files[i])) {
/*recursive loop for nested folders files*/
await this.makezip(files[i], zip, i);
}
}
return zip;
}
async urlToPromise(url) {
return await new Promise(function (resolve, reject) {
JSZipUtils.getBinaryContent(url, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
That usage of Promise helps you.
function sureify<T, U = Error>(promise: Promise<T>) {
return promise
.then((data) => [data, undefined] as [data: T, error: undefined])
.catch((error: U | undefined) =>
Promise.resolve([undefined, error] as [data: undefined, error: U])
);
}
// Convert from Promise
const [response, error] = await sureify(urlToPromise("url"))

Not getting data after dependent api call using async problem node

I am calling API to fetch data on the basis of that data I am calling different APIs which is based on condition.
I have used a promise to maintain the async code as well but no luck so far. At the end of the block, I want every data pushed inside array but I am getting a blank array.
async (body, nextCall) => {
var tmpArryOfModuleList = []
var bodyData = body.data
var promise = new Promise((resolve, reject) => {
bodyData.forEach(element => {
if (element.hasCRUD === '0') {
var options = {
method: 'GET',
url: `${apiURL}/api/fetchAllCharts`,
headers:
{
Authorization: token
}
};
request(options, function (error, response, dashboardData) {
if (error) {
return nextCall({
error: error
})
}
var parsedDashboardData = JSON.parse(dashboardData)
for (var i = 0; i < parsedDashboardData['data'].length; i++) {
var val = element.name + " - " + parsedDashboardData['data'][i]['name']
var randomID = Math.random().toString(36).slice(2)
tmpArryOfModuleList.push({ "_id": randomID, "submodule": val })
}
});
} else if (element.hasCRUD == '1') {
var options = {
method: 'GET',
url: `${apiURL}/api/fetchAllActions`,
headers:
{
Authorization: token
}
};
request(options, function (error, response, crudData) {
if (error) {
return nextCall({
error: error
})
}
var parsedcrudData = JSON.parse(crudData)
for (var i = 0; i < parsedcrudData['data'].length; i++) {
var val = element.name + " - " + parsedcrudData['data'][i]['name']
var randomID = Math.random().toString(36).slice(2)
tmpArryOfModuleList.push({ "_id": randomID, "submodule": val })
}
});
} else {
console.log('no data found')
reject('No Data Found')
}
})
resolve(tmpArryOfModuleList)
})
console.log('tmpArryOfModuleList', tmpArryOfModuleList)
}
What am I doing wrong? How can I achieve the result on the last array?

Don't work function with promise

I try this code:
function addNewCars(req, res) {
let CarsList = req.body;
carListParsing(carList)
.then(function () {
console.log('OK');
res.status(200).send('OK');
}).catch(function (err) {
res.status(200).send(err);
});
}
function carListParsing (data) {
return new Promise(function (resolve, reject) {
let newCar = {};
newCar.name = data.car_name;
validateCar(newCar).then(function (data) {
console.log('validate result1: ', data); //this line doesn't show
//if I get validation result, I can use next function createCat()
resolve(data);
}).catch(function (err) {
reject(err);
});
});
}
function validateCar(data) {
db.cars.findAll({where: {name: data.name}}).then(function (org) {
if (org.length < 1) {
console.log('validate1: OK'); //work
return data;
} else {
console.log('validate2: already exist'); //work
return new Error('The ' + data.name + ' car is already exist.');
}
}).catch(function (err) {
return err;
});
}
I neet to validate data => Car name, if car not exist then create new car and perform next logic, example park car. If car found, then perform function park car.
Avoid the Promise constructor antipattern in carListParsing, and return your result promise from validateCar!
function addNewCars(req, res) {
// CarsList is a typo
carListParsing(req.body)
.then(function () {
console.log('OK');
res.status(200).send('OK');
}, function (err) { // more appropriate than catch
res.status(200).send(err);
});
}
function carListParsing (data) {
let newCar = {
name: data.car_name
};
// don't call `new Promise`
return validateCar(newCar).then(function (data) {
console.log('validate result1: ', data); //this line doesn't show
// if I get validation result, I can use next function createCat()
return data; // don't resolve
});
}
function validateCar(data) {
return db.cars.findAll({where: {name: data.name}}).then(function (org) {
// ^^^^^^
if (org.length < 1) {
console.log('validate1: OK'); //work
return data;
} else {
console.log('validate2: already exist'); //work
throw new Error('The ' + data.name + ' car is already exist.');
// ^^^^^ probably what you actually wanted
}
}) // don't ignore errors
}

What is the correct way/can you chain two AngularJs service calls and then perform a function with the returned data?

I would like to chain these two service calls, and with the results perform a forEach loop to filter my data, but get a TypeError: "SocialMediaUserService.channelProfiles is not a function" message in Chrome.
However, this works in IE, and no warning or message. :)
function getChannelProfiles() {
GetUserAccessService.returnBrandProfileID().then(function (brandProfileID) {
SocialMediaUserService.channelProfiles().then(function (channelProfiles) {
channelProfiles.forEach(function (channel) {
if (channel.brand_profile_id === brandProfileID && channel.channel_type === 'facebook') {
$scope.facebookChannels.push(channel.channel_url);
console.log($scope.facebookChannels);
}
});
});
});
}
EDIT: This is my SocialMediaUserService.channelProfiles service call:
this.channelProfiles = function () {
var channelProfiles = pullSocialMediaData('list_channel_profiles.json');
console.log("Channel Profiles Logged: " + channelProfiles);
return channelProfiles;
}
This is my SocialMediaUserService.returnBrandProfileID service call:
this.returnBrandProfileID = function () {
var brandProfileID = $q.defer();
if (angular.isUndefined($sessionStorage.brandProfileID)) {
GetDataService.getItems('GetUserAccess/' + $cookies.get('authenticationID'))
.success(function (accessObject) {
brandProfileID.resolve(accessObject.FusewareID);
})
.error(function (error, status) {
console.error('Fuseware API error: ' + error + ' Status message: ' + status);
});
}
else {
brandProfileID.resolve($sessionStorage.brandProfileID);
}
return brandProfileID.promise;
};
Edit 2: This is the pullSocialMediaData function:
function pullSocialMediaData(url) {
var userData = $q.defer();
GetFusionDataService.getItems(url)
.success(function (data) {
userData.resolve(data);
})
.error(function (error, status) {
});
return userData.promise;
}
Thank you!
The SocialMediaUserService.channelProfiles might be designed like this :
this.channelProfiles = function () {
var channelProfilesPromise = new Promise(function (resolve, reject){
pullSocialMediaData('list_channel_profiles.json').then(function(result){
console.log("Channel Profiles Logged: " + result);
resolve(result);
});
});
return channelProfilesPromise
};

Value of var goes back to empty after exiting function?

So I have an api request inside of a function thats placed in my Service script.. I have defined the variable "curruser" outside of the function so I can keep its value, however after exiting the follow Scirpt, curruser is empty??
services.js
function fbUserInfo() {
ngFB.api({
path: '/me',
params: {
fields: '/*params*/'
}
}).then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
});
}
So the console.log would return the proper JSON object I retrieved from facebook.. but when I return it in the return statement
return {
userInfo: function() {
fbUserInfo();
console.log(curruser);
return curruser;
}
it returns that curruser is an empty object! I did write
var curruser;
into the first line inside the ".factory"
you have to use then() since fbUserInfo() is async function
return {
userInfo: function() {
$.when(fbUserInfo())..then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
}).then(function(){
console.log(curruser);
return curruser;
})
}
Haven't tested this but might work.
var curruser;
function fbUserInfo( callback ) {
ngFB.api({
path: '/me',
params: {
fields: '/*params*/'
}
}).then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
callback(curruser);
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
});
}
return {
userInfo: function( callback ) {
fbUserInfo( function(data){
console.log(data);
callback(data);
});
}

Categories

Resources