How do I pass a context into a Javascript promise [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I will be the first to admit, I don't always get JS Promises. So if this is a stupid question I apologize in advance. =) Given the code below, I need to set a property in the class that contains this function (i.e. I need to call "this" within the fullfullment methods and have it refer back to the class.
I saw a few things that related to setting context, but they also required closures (()=>{...code..}) which don't work so well in Internet Explorer. And we can hate on that browser all we want but at the end of the day its a requirement that this code works in IE.
So my question today is, how do I get a reference to this passed into the methods below?
var result = this.saveChanges();
return Promise.resolve(result).then(function (value) {
return value.HasError === false;
}, function (value) {
if (value && value.responseJSON) {
return value.responseJSON.HasError === false;
}
return false;
});
Your assistance is appreciated immeasurably.

You can declare a variable that references this and use that in the function.
var self = this;
var result = this.saveChanges();
return Promise.resolve(result).then(function (value) {
self.someProperty = true;
return value.HasError === false;
}, function (value) {
if (value && value.responseJSON) {
return value.responseJSON.HasError === false;
}
return false;
});

Related

Javascript function returning undefined even though console.log shows correct value [duplicate]

This question already has answers here:
forEach/for...in not returning values? [duplicate]
(5 answers)
Closed 5 years ago.
I've checked other questions that seem to be duplicates but none of them have solved my problem. I have this simple function that loops through an array of rule objects and returns the one with the matching "type":
$ctrl.findRule = function(ruleName){
$ctrl.rules.forEach(function(rule){
if(rule.type === ruleName){
console.log("returning rule: " + rule.type);
return rule;
}
});
return null;
};
I call this function as follows:
var wordCountRule = $ctrl.findRule("word_count");
console.log(wordCountRule);
I see on the console returning rule: word_count and then the console.log(wordCountRule) displays undefined. I have tried everything and I have no idea why this is happening.
Thanks!
The issue is because you're returning the value from the inner forEach handler function, not your outer findRule() function.
To fix this you could define a variable to hold the return value and amend that within the inner scope:
$ctrl.findRule = function(ruleName) {
var returnVal = null;
$ctrl.rules.forEach(function(rule) {
if (rule.type === ruleName) {
returnVal = rule;
}
});
return returnVal;
};
However you should note that it you're looking for a single value you can use find() directly, without the need to loop explicitly:
$ctrl.findRule = function(ruleName) {
return $ctrl.rules.find(function(rule) {
return rule.type === ruleName;
});
};
Taking the above example a step further, by using ES6 syntax it can be reduced to just this:
$ctrl.findRule = ruleName => $ctrl.rules.find(rule => rule.type === ruleName);

why i always getting back as undefined? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I am new to Javascript, and Trying to write a function inside a function, but it always show undefine.
function csnotebook(){
function calculate_mw(peptide){
var total_mw=0;
var split_peptide = peptide.split("-");
// Check if the blog id is found in database
Aa.findOne({ three_letter: split_peptide[1] }, (err, aa) => {
// Check if the id is a valid ID
if (!aa) {
console.log("wrong aa");
}else{
total_mw += aa.mw;
}
return total_mw;
});
}
var publicAPI = {
mw: calculate_mw
};
return publicAPI;
}
var fred = csnotebook();
var totalmw = fred.mw("Ala-Cys");
console.log(totalmw);
I assume i can find the corresponding value mw from database, but totalmw, I always get undefined for some reson, anybody know why? Thank you!!
The inner function calculate_mw doesn't return anything, so the return value of a function is undefined unless you return something.
If you want to return the result of the Aa.findOne you should:
return Aa.findOne(...

How I can return a string from a javascript callback [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
How I can return a string from a javascript callback
I have two functions, main function is working on loaded.
and another function is used to calling web service.
I would like to know how can JS return the string value to main function.
thanks
function thisCallJSON(webServiceURL) {
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
gadgets.io.makeRequest(webServiceURL, function(response)
{
if(response.data && response.text)
{
var jsondata = response.data;
for (var key in jsondata)
{
var value = jsondata[key];
//alert("Member Name : "+value["memNm"]);
}
}
else
{
//alert("Member Name : Not Found !");
}
}, params);
}; function main(){
var txt_string = "";
txt_string = thisCallJSON("http://192.100.1.59");
}
You can assign the value to the variable in the scope of the main function, but it won't happen before the main function is finished executing because of the event loop. Instead, you should put your code inside the callback, or better yet, look at how you would use javascript promises to accomplish this.

return statement in forEach won't stop execution of function [duplicate]

This question already has answers here:
What does `return` keyword mean inside `forEach` function? [duplicate]
(2 answers)
Closed 2 years ago.
I am trying to determine whether or not an array holds a certain item. If it does, I would like to hold the function, otherwise it should get added.
function addPacking(item){
data.packings.forEach(function(entry){
if(item.name == entry.name){
return;
}
});
data.packings.push(item);
}
Unfortunately, the data is pushed even when the if condition is met. How do I prevent this behaviour without using an else condition?
(I do not want to use else because my actual code is a lot more complex than this and I'd like to keep it readable)
Edit:
Does forEach execute asynchronously?
Old ways are sometimes the best. It's because you're passing a delegate function when calling .forEach. The return within the delegate is getting lost, and isn't applying to anything. To get your desired result, you'll want to exit the calling function addPacking. This can be done using a simply for loop.
function addPacking(item){
for (var i = 0; i < data.packings.length++; i++) {
if (item.name == data.packings[i].name) {
return;
}
}
data.packings.push(item);
});
This approach also supports older browsers, unlike some, every and forEach
You can't stop forEach execution other than throwing an exception (#Yoshi). Which should not be considered as an option to affect program code flow (#Me).
What you can do is to use another method some or every
function addPacking(item){
var contains = data.packings.every(function(entry){
return item.name != entry.name;
});
if(contains) {
data.packings.push(item);
}
}
Or
function addPacking(item){
var conatins = !data.packings.some(function(entry){
return item.name == entry.name;
});
if(contains) {
data.packings.push(item);
}
}
OLD question but in case someone else comes across this thread.
If you are using ECMAScript 6 you can use the Array find() method
var found = myArray.find(function (element) { return element === arrayToFind; });
so for this particular scenario would be:
function addPacking(item){
var foundItem = data.find(function(entry){ return entry.name == item.name});
if (foundItem) data.packings.push(foundItem);
}
see http://www.w3schools.com/jsref/jsref_find.asp for another worked example.
Return just aborts the function called in forEach, not your addPackings function.
function addPacking(item){
var isInPackings = false;
data.packings.forEach(function(entry){
if(item.name == entry.name){
isInPackings = true;
}
});
if (!isInPackings)
data.packings.push(item);
}
Yo are just returning from the child function but not from the parent function
function addPacking(item){
var check=false;
data.packings.forEach(function(entry){
if(item.name == entry.name){
check=true;
return;
}
});
if (check) return;
data.packings.push(item);
}

Run function only once - functional programming JavaScript [duplicate]

This question already has answers here:
Implementing a 'once' function in JavaScript
(3 answers)
Closed 8 years ago.
I have a code below,
var a = 0;
var addByOne = doOnce(function() { a += 1; });
// I need to define a doOnce function here
// Run addByOne two times
addByOne();
addByOne();
This will result the variable a holds 2 as its value. My question is, how do I make the doOnce function so that it will result in running the function inside doOnce (in the case above, function () { a += 1; } ) just one time. So no matter how many times addByOne is called, variable a will be incremented just once.
Thanks
This can be achieved by creating a doOnce function which returns a wrapper for calling the passed function if it has not already been run. This may look something like this;
doOnce = function(fn) {
var hasRun = false,
result;
return function() {
if (hasRun === false) {
result = fn.apply(this, arguments);
hasRun = true;
}
return result;
}
}
Try this:
function doOnce(fn) {
// Keep track of whether the function has already been called
var hasBeenCalled = false;
// Returns a new function
return function() {
// If it has already been called, no need to call it again
// Return (undefined)
if (hasBeenCalled) return;
// Set hasBeenCalled to true
hasBeenCalled = true;
return fn.apply(this, arguments);
}
}
If you want, you can keep track of the return value and return that instead of undefined.

Categories