Call a method inside Promise.all from Redux Saga - javascript

In the code block below, var ret=that.sendSMTPEmailForOrderPlaced(orderData); is not getting executed. The console is printing "before calling," but it is not printing "inside sendSMTPEmailForOrderPlaced" message. Getting error TypeError: Cannot read property 'sendSMTPEmailForOrderPlaced' of null in createNewOrderHistory method.createNewOrderHistory is called from Redux Saga
const result = yield call(MyProfileRepository.createNewOrderHistory, data);
What is wrong with the code below?
class MyRepository {
constructor(callback) {
this.callback = callback;
}
createNewOrderHistory(tableData) {
var that = this;
const AuthStr = 'Bearer ' + getToken();
let promises = [];
tableData.map((tableData, index) => {
var data = {
invoice_id: tableData.invoiceID.toString(),
};
promises.push(axios.post(`url`, data, {
headers: { Authorization: AuthStr },
}));
});
return Promise.all(promises).then(function(results) {
console.log("before calling")
var ret = that.sendSMTPEmailForOrderPlaced(orderData);
console.log("after calling")
console.log(ret);
return (results);
}).catch(error => {
return (error);
});
}
sendSMTPEmailForOrderPlaced(data) {
console.log("inside sendSMTPEmailForOrderPlaced")
const response = axios.post(`url`, data).then((response) => {
return response.data;
}).catch((error) => {
console.log(error);
return (error);
});
return response.data;
return null;
}
}
export default new MyRepository();

It's hard to test your code, but I believe that #Keith had the right idea in his comment. So to test it I had to change 'url' and so on. But this code should give you a good idea on how to write it:
const axios = require('Axios');
class MyRepository {
async createNewOrderHistory(tableData) {
var that = this;
const AuthStr = 'Bearer '; // + getToken();
const header = { headers: { Authorization: AuthStr } };
let promises = tableData.map((tableData, index) => {
var data = { invoice_id: tableData.invoiceID.toString() };
return axios.post('https://jsonplaceholder.typicode.com/posts', data, header);
});
const results = await Promise.all(promises).then(async (results) => {
console.log("before calling")
var ret = await that.sendSMTPEmailForOrderPlaced(results.data);
console.log("after calling", ret);
return (results);
}).catch(error => {
return (error);
});
console.log(results.map(a => a.data));
}
async sendSMTPEmailForOrderPlaced(data) {
console.log("inside sendSMTPEmailForOrderPlaced")
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', data);
return response.data;
} catch (error) {
return error;
}
}
}
var repo = new MyRepository();
repo.createNewOrderHistory([{ invoiceID: 'test' }, { invoiceID: 'test2' }, { invoiceID: 'test3' }]);
If you want to run this, past it into a test.js file in an empty folder, then run the following in the same folder:
npm init -y
npm i axios
node .\test.js

Related

How can I get value in [Object]

I'm working on coinmarketcap.com api and I need only name and price and save to Mongo. It is working but at the end undefined value returned. Price value is under the quote. What is wrong ?
const axios = require('axios');
let response = null;
new Promise(async (resolve, reject) => {
try {
response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'myKey',
},
});
} catch(ex) {
response = null;
console.log(ex);
reject(ex);
}
if (response) {
const coin = response.data;
console.dir(coin, { depth: null });
console.log(coin.data.map(a => { a.name, a.quote.price}));
resolve(coin);
}
}
);
You shuldn't be wrapping this in another Promise (see: What is the explicit promise construction antipattern and how do I avoid it?) , just make a method which is async
async function getCoin(){
try {
const response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'YOURKEY',
},
});
const coin = response.data;
console.dir(coin, { depth: null });
return coin;
} catch(ex) {
console.log(ex);
throw ex;
}
}
quote contains prices identified by their keys like this:
"quote": {
"USD": {
"price": 42177.91536878145,
"volume_24h": 18068350418.6717,
"volume_change_24h": 8.1323,
"percent_change_1h": -0.02144759,
"percent_change_24h": -0.48235688,
"percent_change_7d": -0.65364542,
"percent_change_30d": -1.87762517,
"percent_change_60d": -13.80076009,
"percent_change_90d": -30.24448455,
"market_cap": 799599134284.9932,
"market_cap_dominance": 42.7605,
"fully_diluted_market_cap": 885736222744.41,
"last_updated": "2022-02-14T09:35:00.000Z"
}
}
so in order to solve the bug, you need to specify the proper key here (USD for example):
I tested this code and it works please copy it inside the separate js file and check the result(Replace your API key):
const axios = require('axios');
let response = null;
async function getCoin(){
try {
const response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'KEY',
},
});
const coin = response.data;
const result = coin.data.map(a => ({ name: a.name, price: a.quote['USD'].price}))
console.log(result)
return coin;
} catch(ex) {
console.log(ex);
throw ex;
}
}
getCoin()
const axios = require("axios");
async function fetchData() {
try {
const response = await axios.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2",
{
headers: {
"X-CMC_PRO_API_KEY": "myKey",
},
}
);
return [response, null];
} catch (error) {
return [null, error];
}
}
// in your calling function code base
const [response,error] = await fetchData()
if(response){
// handle response object in calling code base
const coin = response.data
}
if(error){
// handle error explictly in calling code base
}
Getting price in quote.USD or quote['USD'] and also need to return object of name and price using map.
So Try this:
const axios = require('axios');
let response = null;
new Promise(async (resolve, reject) => {
try {
response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': '5345bcb4-0203-4374-bef6-d67a89a6d216',
},
});
if (response) {
const coin = response.data;
cointData = coin.data.map(a => ({ name: a.name, price: a.quote.USD.price }))
resolve(cointData);
}
} catch (ex) {
response = null;
console.log(ex);
reject(ex);
}
});

Mutiple Axios return not able to return the value but in cosole it is coming

Multiple Axios return not able to return the value but in console it is coming
first function is able to return the data>
second and 3rd is not able to do>
< the first function is able to return the data>
<the second and 3rd is not able to do>
async getdata() {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result = await axios.get(url, config);
console.log(result.data); // --------------> data is coming here
return result.data; //------------>able to return the data from here
}
async getfame() {
var res = await this.getdata()
res.map(async(item: any) => {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result1 = await axios.get(url, config);
console.log(result1.data); // -----------------> data coming here
return result1.data; //------------> not able to return the data from here
//return axios.get<string>(url, config);
})
}
async getfix() {
var res1 = await this.getdata()
res1.map(async(item: any) => {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result2 = await axios.get(url, config);
console.log(result2.data); // -----------------> data coming here
return result2.data; //------------> not able to return the data from here
//return axios.get<string>(url, config); //-------------> tried this way but still not coming
})
}
In your second and third functions, you're returning those axios calls inside an array map. The outer function is not returning anything.
If you add a return before each .map() call, then the functions will return an array of your expected results.
async getfame() {
var res = await this.getdata()
return res.map(async(item: any) => {
/* ... */
return result1.data;
})
}
async getfix() {
var res1 = await this.getdata()
return res1.map(async(item: any) => {
/* ... */
return result2.data;
})
}

How to set two interceptors in axios

I have two functions that using axios post information to different APIs I created with node and express. Both of them have an interceptor as I get a response from by backend with messages, errors, and other information. Yet when I post the to the second url ("/users/login") the first interceptor still fires off (in the addUser instead of the findUser function) even though it is not in the same function. How do I fix this?
async function addUser(user) {
const config = {
headers: {
"Content-Type": "application/json",
},
};
try {
const interceptorResponse = axios.interceptors.response.use(
(response) => {
if (typeof response.data === "object") {
let success = response.data.registerSuccess;
let errors = response.data.errors;
let data = response.data.data;
let message = response.data.message;
setData(() => {
return { ...data, errors, registerSuccess: success, message };
});
}
return response;
}
);
await axios.post("/users/register", user, config);
axios.interceptors.request.eject(interceptorResponse);
} catch (err) {}
}
async function findUser(user) {
const config = {
headers: {
"Content-Type": "application/json",
},
};
try {
axios.interceptors.response.use((response) => {
console.log(response);
if (typeof response.data === "object") {
let loginSuccess = response.data.data.loginSuccess;
let message = response.data.message;
console.log(response.data);
setData(() => {
return { ...data, loginSuccess, message };
});
}
return response;
});
await axios.post("/users/login", user, config);
} catch (error) {}
}

How to run a Node script

I need to be able to run a node script to delete an object from an external API. So I should be able to run this command:
node server.js Customer55555
And it should delete the object.
I have called to the API by using Axios.
const axios = require("axios");
const API = "http://dummy.restapiexample.com/api/v1/employees";
function getAllEmployees() {
axios
.get("http://dummy.restapiexample.com/api/v1/employees")
.then(response => {
// console.log(response.data);
console.log(response.status);
function filterEmployee() {
const employeeData = response.data;
employeeData.filter(employee => {
console.log(employee);
});
// console.log(employeeData);
}
filterEmployee();
})
.catch(error => {
console.log(error);
});
}
function deleteEmployee() {
axios({
method: "DELETE",
url: "http://dummy.restapiexample.com/api/v1/delete/36720",
headers: { "Content-Type": "application/json" }
})
.then(
// Observe the data keyword this time. Very important
// payload is the request body
// Do something
console.log("user deleted")
)
.catch(function(error) {
// handle error
console.log(error);
});
}
// getAllEmployees();
deleteEmployee();
I am able to get an individual object, but I need to figure out how to delete it by running the command above.
You can do something like this:
const axios = require("axios")
const API = "http://dummy.restapiexample.com/api/v1/employees"
async function getAllEmployees(filter = null) {
try {
const response = await axios.get("http://dummy.restapiexample.com/api/v1/employees")
console.log(response.status)
let employeeData = response.data
if (filter) {
// return only employees whose name contains filter.name
employeeData = employeeData.filter(({ employee_name }) => {
return employee_name.toLowerCase().indexOf(filter.name.toLowerCase()) >= 0
})
}
return employeeData
} catch(error) {
console.error(error)
return []
}
}
async function deleteEmployee({ id }) {
if (!id) {
throw new Error('You should pass a parameter')
}
try {
const response = await axios({
method: "DELETE",
url: `http://dummy.restapiexample.com/api/v1/delete/${id}`,
headers: { "Content-Type": "application/json" }
})
console.log("user deleted " + id)
} catch(error) {
// handle error
console.error(error)
}
}
async function main(params) {
const employees = await getAllEmployees({ name: params[0] || '' })
// Returns a promise to wait all delete promises
return Promise.all(employess.map(employee => deleteEmployee(employee)))
}
// process.argv contains console parameters. (https://stackoverflow.com/questions/4351521/how-do-i-pass-command-line-arguments-to-a-node-js-program)
main(process.argv.slice(2)).then(() => {
// returns 0 (Success) (https://stackoverflow.com/questions/5266152/how-to-exit-in-node-js)
process.exit(0)
}).catch(() => {
// returns 1 (error)
process.exit(1)
})
You should adapt this sample to get proper filtering and error reporting.

How do I return the contents of this function to the client side?

I have a function that I call using
fetch(http://localhost:8888/.netlify/functions/token-hider?
stateName=' +stateName)
on my client side.
the token-hider function looks like this:
const qs = require("qs");
const fetch = require("node-fetch");
var alertEndpoint = "";
var parkEndpoint = "";
var parksWithAlerts = "";
exports.handler = async function getURLS(event, context, callback)
{
// Get env var values defined in our Netlify site UI
const {api_key, alert_api_url, park_api_url} = process.env;
var stateName =event.queryStringParameters.stateName;
alertEndpoint = `${alert_api_url}${stateName}${api_key}`;
parkEndpoint = `${park_api_url}${stateName}${api_key}`;
getData();
async function getData(alertsArea, alertHeader) {
const [getAlertData, getParkData] = await
Promise.all([fetch(alertEndpoint), fetch(parkEndpoint)] );
var alertResults = await getAlertData.json();
var parkResults= await getParkData.json();
var alertData = alertResults.data;
var parkData = parkResults.data;
parksWithAlerts = parkData.map(park => {
park.alertData = alertData.filter(alert => alert.parkCode ===
park.parkCode);
return park
});
console.log(parksWithAlerts);
}
console.log(callback);
};
how could I return the contents of parksWithAlerts back to the client side after this function is finished?
Try to learn more about callback functions in Javascript.
It is right there in your code, the callback that you are printing is actually suppose to be called after you have executed your code and you can do like this callback(parksWithAlerts);.
While calling the function getURLS you will provide the function which is suppose to get called with args.
Examples : https://www.geeksforgeeks.org/javascript-callbacks/
Here is an example with error handling and returning a response type of JSON
token-hider
import fetch from "node-fetch";
// Get env var values defined in our Netlify site UI
const {api_key, alert_api_url, park_api_url} = process.env;
async function getJson(response) {
return await response.json();
}
const alertEndpoint = stateName => {
return new Promise(function(resolve, reject) {
fetch(`${alert_api_url}${stateName}${api_key}`)
.then(response => {
if (!response.ok) { // NOT res.status >= 200 && res.status < 300
return reject({ statusCode: response.status, body: response.statusText });
}
return resolve(getJson(response))
})
.catch(err => {
console.log('alertEndpoint invocation error:', err); // output to netlify function log
reject({ statusCode: 500, body: err.message });
})
});
}
const parkEndpoint = stateName => {
return new Promise(function(resolve, reject) {
fetch(`${park_api_url}${stateName}${api_key}`)
.then(response => {
if (!response.ok) { // NOT res.status >= 200 && res.status < 300
return reject({ statusCode: response.status, body: response.statusText });
}
return resolve(getJson(response))
})
.catch(err => {
console.log('parkEndpoint invocation error:', err); // output to netlify function log
reject({ statusCode: 500, body: err.message });
})
})
}
exports.handler = function(event, context) {
const stateName = event.queryStringParameters.stateName;
return Promise.all([alertEndpoint(stateName), parkEndpoint(stateName)])
.then(values => {
const [alertData, parkData] = values;
const parksWithAlerts = parkData.map(park => {
park.alertData = alertData.filter(alert => alert.parkCode === park.parkCode);
return park;
});
return {
statusCode: 200,
headers: { 'content-type': 'application/json' },
body: JSON.stringify(parksWithAlerts)
};
})
.catch(error => {
return error;
});
};
NOTE: If you are trying to hide the token, make sure to not deploy this from a public repository on Netlify.
Also, this code has not been tested 100%, so there may be some things to resolve. The response layout and structure is something I use in a few of my lambda functions on Netlify.

Categories