Can setInterval() be put in the last .then() method in Javascript? - javascript

A new javascript question, again, and again...
(Updated)
a is a string where I input a word, it will then be sent to a Dictionary API and do the fetchApi(). After getting the result, if a matches the result[0].word, it will trigger the function Func1(), if not then it will trigger the other function Func2().
What I'd like to ask is there any way to use setInterval() for the function data(result), after deleting the part .then(result => data(result)) in the function fetchApi(a)? Or can I only put setInterval() for both functions Func1() and Func2()?
Thank you very much!
var a = "";
function fetchApi(a) {
let url = `${url}${a}`;
fetch(url).then(res => res.json()).then(result => data(result));
}
function data(result) {
// console.log(result);
if (a == result) {
Func1();
} else {
Func2();
}
}

Putting setInterval() on data() will not do anything because result will never change once it has returned. You need to call the whole fetchApi function again if you're expecting the result to be updated later on.

Related

Get a value from a callback in another function NodeJS

I'm desperately trying to recover the value of a callback function but I have no idea how to do that. I have a function where I execute this code:
if (final.error !== undefined) {
console.log("Initial authentication:", final.error_description, "Please refresh the authentication grant");
extAuthCallback(84);
} else {
tokens.set('access_token', final.access_token)
.set('expires_in', final.expires_in)
.set('refresh_token', final.refresh_token)
.set('refresh_date', moment())
.write()
extAuthCallback(1);
}
});
Who performs this function:
function extAuthCallback(result) {
return result;
}
And which is called by this variable:
let authentication = auth.extAuth(access_token, auth.extAuthCallback);
I would like my `authentication' variable to take the value returned in the callback, and I have no idea how to do that. Returning the callback function to my original function doesn't work.
You could use a promise, would need to use an async function as well though.
function asyncExtAuth(access_token) {
return new Promise(resolve => {
auth.extAuth(access_token, resolve);
});
}
let authentication = await asyncExtAuth(access_token);

Have a question about react hook usage for "useEffect"

// ....react component
const [fruitDetail, setFruitDetail] = useState(null);
useEffect(() => {
if (!fruitName) {
return;
}
// Method 1
getFruit(fruitName).then((data) => {
console.log(data);
setFruitDetail(data);
});
// Method 2
getFruit(fruitName).then(setFruitDetail);
}, [fruitName]);
return fruitDetail;
I'm very curious about that why Method 1 and Method 2 are equivalent. Is it a Syntactic sugar ?
You can look at method 1 as an explicit way of calling the function. The .then method gets passed the result of getFruit(fruitName)..which you could name whatever you wanted, in your case you chose to call it data. Then you used that variable, data to make two function calls. So you explicitly refer the response by the variable name data.
In your method 2, the variable is implicit. Meaning, because of the way .then works, Javascript knows .then expects one argument, which is the result of the getFruit(fruitName). The .then method takes the result and passes it as the first argument to setFruitDetail...it would also be the same thing to say getFruit(fruitName).then(response => setFruitDetail(response)).You just don't need to specifically put the response variable since it is the only thing being passed and only thing being used.
then function calls any passed function/callback with the promise result.
setFruitDetail is just a function so is ()=>{} albeit anonymous one. You can also pass console.log and see what it does like this getFruit(fruitName).then(console.log). I would suggest to have a look at basic promise implementation.
Is it a Syntactic sugar ?
No, it is not. Because, it's just the another way to pass callback function.
There is example to make clear:
let api = async () => {
return new Promise((solve, reject) => {
setTimeout(() => solve('result'), 1000);
})
};
//your setFruit is a callback. Let example:
let setFruitDetail = (fruit) => console.log(fruit);
//there is no different when you pass a call back into then function.
api().then(setFruitDetail);
api().then(fruit => setFruitDetail(fruit));
//you can imagine that in then function will get param you input into to call a callback.
let otherApi = (callback) => {
let result = "result";
callback("result");
}
otherApi(setFruitDetail);
otherApi(fruit => setFruitDetail(fruit));

Function body not executed if not passed directly to requestAnimationFrame

So I had this originally:
requestAnimationFrame(appendItemsFragment(itemsFragment, appendItemsFragmentCallback));
But I needed to do something more, so I transformed it to
requestAnimationFrame(() => {
appendItemsFragment(itemsFragment, appendItemsFragmentCallback);
myNewFunctioncall();
});
Original function is defined as:
const appendItemsFragment = (itemsFragment, callback) => () => {
itemsContent.appendChild(itemsFragment);
destroySpinner();
if (callback) {
callback();
}
};
But in the modified version of the requestAnimationFrame, the function appendItemsFragment is not executed (I put an alert() and it does not work, I press F10 two times and it comes back to the end of requestAnimationFrame). Why is that?
appendItemsFrament() returns a callback function. In the original code, requestAnimationFrame() executes that callback. Now you need to do it in your wrapper function.
requestAnimationFrame(() => {
appendItemsFragment(itemsFragment, appendItemsFragmentCallback)();
myNewFunctioncall();
});
However, this will call appendItemsFragment() for every frame that's displayed, which will repeatedly append the item fragment, which is probably not what you want. You need to call it once, save the result, and then call that in your wrapper function.
let callback = appendItemsFragment(itemsFragment, appendItemsFragmentCallback);
requestAnimationFrame(() => {
callback();
myNewFunctioncall();
});

How do I get this if statement to finish executing before the rest of the code runs?

This is a simple version of what I'm trying to do in my application. I have an if statement which evaluates the result of a function call and then populates an array if the statement comes back as true. AFTER the if statement is completely finished, I want to run some more code such as the console.log as seen below.
I understand that the if's evaluation is taking too long to finish and javascript just continues to the console.log because of its asynchronicity. How do I make the code wait for the if statement to complete?
var tabs = [];
if (isTrue()) {
tabs.push('some string');
}
console.log(tabs[1]);
function isTrue() {
setTimeout(function() {
return true;
}, 500)
}
You can just wrap your code in a Promise and consume the returned values by calling then on it:
var tabs = [];
isTrue().then(res => {
if (res) {
tabs.push('some string');
}
return tabs;
}).then(arr => {
console.log(arr);
});
function isTrue() {
//Just wrap your existing code in a Promise constructor
return new Promise((resolve, reject) => {
setTimeout(() => {
//Pass whatever value you want to consume later to resolve
resolve(true);
}, 500)
});
}
You could pass a callback to the isTrue() function, something like:
function isTrue(_callback) {
setTimeout(function() {
// code here
// Call the callback when done
if (typeof(_callback) === 'function')
_callback(tabs);
});
}
function showTabs(tabs) {
console.log(tabs[1]);
}
isTrue(showTabs);
Ought to work.
Using modern javascript, you can achieve that using promises and async/await:
const isTrue = () => new Promise(resolve => setTimeout(resolve, 500, true));
// you can only use `await` inside an `async` function
async function main() {
// better use `let` instead of `var` since `let` is block scoped,
// see:
// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let>
let tabs = [];
if (await isTrue()) {
tabs.push('some string');
}
// array's index start by 0, not 1
console.log(tabs[0]);
}
main();
(this code also use arrow functions for isTrue.)
isTrue() returns undefined. The return true inside of the setTimeout callback will return back to the timeout call, not to the isTrue() call. The code executes immeadiately and there is no asynchronity involved (except for that timer that does nothing).

Identify when nested FOR loops and IF statement with one asynchronous function call are done

I have a function with nested for-loops and IF statements and one call of an asynchronous function. The structure looks similar to this:
search(){
// for loop 1
for (let i in object){
// IF statement 1
if (condition1){
// for loop 2
for (let o in object[i]){
// IF statement 2
if (condition2){
// call of an asynchronous function
this.asyncFunction().then( data => {
this.result.push(data)
});
}
}
}
}
}
I want to call one function (let's say goToNextPage() ) as soon as all loops are done and all async-function calls are completed and, thus, my this.result object is completed.
However, I don't know how to manage this. I tried to work with counters, to know when the last object[i] is handled and when the last object[i][o] was handled to call goToNextPage() afterwards. But this doesn't work properly, if the last object fails one if statement. Then goToNextPage() is called, while the async function of the second to last object is still running.
And I can't just call goToNextPage() within
this.asyncFunction().then( data => {
this.result.push(data)
// call it here, if last element is reached
});
since then it would not be called if the last element doesn't meet one of the IF statements.
I hope it's understandable what my problem is and that there is a solution for this...
Thank you for your time!
Koleman answered this perfectly on the official Ionic forum and thereby helped me with the solution: Link
His approach is to insert promises in the structure and to use Promise.all(promises).then(...) to wait until all promises are resolved.
search(){
let promises = [];
// for loop 1
for (let i in object){
// IF statement 1
if (condition1){
// for loop 2
for (let o in object[i]){
// IF statement 2
if (condition2){
let promise = new Promise((resolve, reject) => {
this.asyncFunction().then( data => resolve(data));
});
promises.push(promise);
}
}
}
}
return new Promise((resolve, reject) => {
if(!promises.length){
reject('Something went worng!');
}else{
Promise.all(promises).then((results) => {
this.result = this.result.concat(results);
resolve('We done it!');
});
}
});
}
search().then(
successText => {
console.log(statusText);
console.log(this.result);
},
failText => {
console.log(failText);
}
);

Categories

Resources