How to get data from Promise function - javascript

I have a problem don't know why i can't get return data from the function on another file, here what i try
my file.js
const psm = require("../services/psm");
psm.show(12).then((res) => console.log(res));
my service.js
const axios = require("../plugins/axios").default;
const module = "psm";
exports.show = async (payload) => {
await axios
.get(`/${module}/${payload}`)
.then((res) => {
return res.data.data;
})
.catch((err) => {
return Promise.reject(err.response);
})
.finally(() => {});
};
i get undefined return..

Problems in your code:
show function doesn't explicitly returns anything; as a result, promise returned by the show function is fulfilled with the value of undefined
Improvements that can be made in your code:
catch and finally blocks are not needed; catch block is unnecessary because rejected promise returned as a result of catch block will need to be handled by the code that calls the show function.
You will need the catch method or block in the calling code anyways. So, just remove the catch block and allow the calling code to catch and handle the error
show function doesn't needs to be async. You can just return the result of axios.get or axios.get(...).then(...)
Final version of "show" method:
exports.show = (payload) => {
return axios
.get(`/${module}/${payload}`)
.then((res) => {
return res.data.data;
});
}
You can call this function as:
psm.show(12)
.then(res => console.log(res))
.catch(error => { /* handle the error */ });
Alternate version of show function:
exports.show = (payload) => {
return axios.get(`/${module}/${payload}`);
}
You can call this version of show function as:
psm.show(12)
.then(res => console.log(res.data.data))
.catch(error => { /* handle the error */ });

Related

How to wait for a function, which contains promises

If we have this function
const getData = () => {
foo()
.then(result => {
return result;
})
.catch(error => {
return error;
});
};
Although getData is not a promise itself, but it contains a promise, which is asyncrnous.
So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.
Thanks.
Currently, getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it.
const getData = () => {
return foo() // <-- here
.then(result => {
return result;
})
.catch(error => {
throw error;
});
};
// Now you can do :
getData().then(...)
// or :
const data = await getData();
In this case, you can also omit the curly braces and the explicit return, and make it implicit :
const getData = () => foo()
.then(result => {
return result;
})
.catch(error => {
throw error;
});
Hey but what's that :
.then(result => {
return result;
})
This does nothing. It takes a value and simply returns it without doing anything. You can remove it.
You can now rewrite getData() this way :
const getData = async () => {
try {
return await foo()
} catch (error) {
throw error;
}
}
For that matter, this :
.catch(error => { throw error; });
or this :
catch (error) { throw error; }
are also pretty useless, they just "relay" (bubble up) the error that has to be caught in the calling function.
Now it's obvious getData does pretty much only one thing, it's returning foo(), which is a Promise. It's only a wrapper around a Promise... so it's actually pretty useless.
Bottom line, detData() is useless altogether. foo is a Promise; writing a function that returns a Promise so you can use it like a Promise is just... a Promise with an extra step. Just use foo directly.
let result;
try {
result = await foo();
} catch (error) {
console.log(error);
}
console.log(result);
This will not work because getData is not returning a value. You can add a return statement before foo call and wait for the return value.
const getData = () => {
return foo();
};
getData().then(data => {
console.log(data);
}).catch(err => {
console.log(err);
});
To wait for an operation you must return a Promise or use a callback. The code snippet below runs and should illustrate how this works. I implemented a sample foo function that is actually asynchronous (wait for 1 second before returning the data '12345'). I used async/await to illustrate how that can work, but you can equally return the result of foo and use then instead.
const foo = () => {
return new Promise(resolve => {
setTimeout(() => resolve('12345'), 1000);
});
}
const getData = async () => {
const data = await foo();
console.log(`Data is ${data}`);
return data;
};
getData()
.then(() => console.log('complete'))
.catch(err => console.log(`oops: ${err}`));
console.log('this prints first since async operation is still pending');

Axios console.log data but return Promise <pending>

I've trying to retrieve the data, but I can't return it, can only see it in the console,
it's a simple axios get function but for some reason, I keep getting Promise even after using async/await.
my goal is to save the data to the memory.
any help would really be appreciated
let fetchTodo = async () => {
await axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(res => console.log(res.data))
.then(res => { return res })
.catch(err => console.log(err))
};
console.log("TEST: ", fetchTodo())
console
Asycn function always returns a promise, to get data from the fetchTodo function you need to create another async function which will await the result returned by fetchTodo(). if you are using react, you can use states and update the state while you are inside the .then chain of the fetchTodo function.
Asycn function always returns a promise. For getting or saving data you need to get it from .then() function. Here you can check the example. Hope so it will help you.
let fetchTodo = async () => {
await axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(res => console.log(res.data))
.then(res => {
// here you can performance your task, save data, send
// response or anything else
return res
})
.catch(err => console.log(err))
};
fetchTodo()
The async/await syntax means a function will return a Promise.
If you want to return the value, you could do something like this:
let fetchTodo = async () => {
try {
const res = await axios.get("https://jsonplaceholder.typicode.com/todos/1");
return res;
} catch (error) {
console.log(error);
}
};
// For the folowing code to work, it must be placed inside a async function as well
const res = await fetchTodo();
console.log(`Test: ${res.data}`);
// If it's a Top level call, use the folowing code
const res = fetchTodo().then( res => {
const data = res.data;
// The rest of your code goes here.
// ...
// ...
// ...
}).catch( error => {
console.log(error);
});
Some more information about it on: How can I use async/await at the top level?

Javascript async function return then-catch promise?

Introduction
I am new in the world of javascript promises and I need to understand how they work correctly...
Until know I have been doing this in my code:
const handleRefresh = () => {
setIsRefreshing(true);
fetchUserData()
.then(async () => { <--------- Using then because I return a promise in fetchUserData
await fetchUserPosts(); <------- Using await here
setIsRefreshing(false);
}).catch(err => { <--------- This will catch the error I have thrown in the function fetchUserPosts or inside the then body
// TODO - Show error
setIsRefreshing(false);
console.log(err)
);
};
const fetchUserData = async () => { <------ async function
const { firebase } = props;
const userId = firebase.getCurrentUser().uid;
const documentRef = firebase.getDatabase().collection("users").doc(userId);
// Fetch all the user information
return documentRef <--------- Returning the promise here
.get()
.then((doc) => {
if (doc.exists) {
// Get all user data
const data = doc.data();
console.log(data);
setUserData(data);
}
})
.catch((err) => {
throw err; <----------- Throwing error
});
};
I don't know if I am doing anti patterns... But basically I need to know if this is a good way and if I am doing this correctly.
Questions
Do I have to declare the fetchUserData function as async to return a promise?
Can I use the async await in the then/catch body?
Can I do this?
const handleRefresh = async () => {
setIsRefreshing(true);
await fetchUserData()
.then(async () => { <--------- Using then because I return a promise in fetchUserData
await fetchUserPosts(); <------- Using await here
}).catch(err => { <--------- This will catch the error I have thrown in the function fetchUserPosts or inside the then body
// TODO - Show error
console.log(err)
);
setIsRefreshing(false);
};
I would really appreciate if someone guides me. Thanks.
the words async and await are only syntactic sugar for then and catch.
This:
fetchUserData()
.then(data => return data )
.catch(error => return error)
is equivalent to:
async function getUserData() {
const userData = await fetchUserData()
return userData
}
Here you are returning anything (success or error). If you want to treat the error here, just put a try/catch clause.
async function getUserData() {
try {
return await fetchUserData()
} catch (e) {
return e.message
}
}
Note that you can only use the await clause within an async function.
1.
Function can return Promise without being declared as async as long as you don't await inside it,
2.
You should not use async-await inside then, simply return a Promise and it'll be resolved in the following then,
3.
When using async-await syntax, Promises are awaited in a declarative way as demonstrated below:
const handleRefresh = async () => {
try
{
const a = await getA()
// pass the result to another Promise
const b = await getB(a)
const c = await getC(b)
} catch (error)
{
handleError(error)
}
};

Axios prints value on console but returns undefined

I have quite an issue for some time and is getting on my nerves and it doesn't make sense. I have used axios on my react frontend and it works perfect when assigning the get value to the state. But when using it in a normal javascript code, I appear to have this following issue: i can print the object's value in the console but it will return only undefined.. Here is my code:
login = () => {
let data;
axios.get('https://myaddress/authenticate')
.then(response => {
data = response;
console.log('data here', data);
})
.catch(error => {
console.error('auth.error', error);
});
console.log('eee', data);
return data;
};
Here we are talking about axios strictly.
You can't return an ajax response because it's asynchronous. You should wrap your function into a promise or pass a callback to login
UPDATE: As #Thilo said in the comments, async/await would be another option, but it will let you set the response to data tho ...
1. Wrap into a promise
login = () => new Promise((resolve, reject)=>{
axios.get('https://myaddress/authenticate')
.then(response => {
resolve(response)
})
.catch(error => {
reject(error)
});
});
// Usage example
login()
.then(response =>{
console.log(response)
})
.catch(error => {
console.log(error)
})
2. Pass a callback
login = (callback) => {
axios.get('https://myaddress/authenticate')
.then(response => {
callback(null,response)
})
.catch(error => {
callback(error,null)
});
};
// Usage example
login((err, response)=>{
if( err ){
throw err;
}
console.log(response);
})
3. Async/Await
login = async () => {
// You can use 'await' only in a function marked with 'async'
// You can set the response as value to 'data' by waiting for the promise to get resolved
let data = await axios.get('https://myaddress/authenticate');
// now you can use a "synchronous" data, only in the 'login' function ...
console.log('eee', data);
return data; // don't let this trick you, it's not the data value, it's a promise
};
// Outside usage
console.log( login() ); // this is pending promise
In ES7/ES8 you can do async/await like a boss:
login = () => {
return new Promise((resolve, reject) => {
axios.get('https://myaddress/authenticate')
.then(response => {
resolve(response)
})
.catch(error => {
console.error('auth.error', error);
reject(error)
});
});
};
async function getData() {
try{
const data = await login()
} catch(error){
// handle error
}
return data;
}
getData()
.then((data) => console.log(data));

Promises in React native

api/index.js
const URL = 'http://10.0.2.2:5000';
const fetching = false;
export default (type, filter, dateFilter, position) => {
if(fetching) return Promise.reject(new Error('Request in progress'));
fetching = true;
return fetch(URL + `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
.then(response => Promise.all([response, response.json()]))
.catch(err => console.log("error catch search:", err.message))
}
I need to put fetching false so in that way i can call this function again, but i dont know where to put it to make it work.
If i create another then like this after the then writen and before the catch like this:
.then(() => fetching = false)
The problem is that it returns false to the place the function is called and NOT the data this is where is called:
actions/index.js
getDataApi(type, filter, dateFilter, position)
.then(res => {
if (res !== false) {
if (state.dataReducer.data.length === 0) {
dispatch(getDataSuccess(res[1]))
} else {
dispatch(getDataSuccess(res[1], state.dataReducer.data))
}
}
})
.catch((err) => console.log(9999, err))
So my problem is that it doesnt enter in the getDataSuccess because is false.I dont know why it cannot send the data to this function and it ends sending the result of fetching = false.
You need another .then so that you can reassign fetching after the response.json() resolves. You should also probably reassign fetching in the catch so that future requests are possible even if there's an error once, and return false in the catch so the .then after getDataAPI will properly ignore failed requests. Also, use let rather than const for fetching:
const URL = 'http://10.0.2.2:5000';
let fetching = false;
export default (type, filter, dateFilter, position) => {
if (fetching) return Promise.reject('Request in progress');
fetching = true;
return fetch(URL + `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
.then(response => Promise.all([response, response.json()]))
.then(([response, responseObj]) => {
fetching = false;
return [response, responseObj];
})
.catch(err => {
console.log("error catch search:", err.message);
fetching = false;
// Choose one, depends what you need.
return false; // If you want to ignore the error and do something in a chained .then()
return Promise.reject(err); // If you want to handle the error in a chained .catch()
})
}

Categories