There is a function that accepts three parameters:
function getAddressStructure(country: number, city: number, region: number) {
}
I need to create a promise that returns data for each varaible and as result returns a common object {countries: [], cities: [], regions: []}
How to do that using promise(s)?
let promise = new Promise((resolve, reject) => resolve());
If you have three different end points that are not dependent on each other then u can use this approach:
export async function handleResponse(response) {
if (response.ok) return response.json();
if (response.status === 400) {
const error = await response.text();
throw new Error(error);
}
throw new Error("Network response was not ok.");
}
export function handleError(error) {
console.error("API failed. " + error);
throw error;
}
export function GetCountries() {
const url = "/countries"
return fetch(url, {
method: "GET",
credentials: "include",
}).then(handleResponse).catch(handleError);
}
export function GetCities() {
const url = "/cities"
return fetch(url, {
method: "GET",
credentials: "include",
}).then(handleResponse).catch(handleError);
}
export function GetRegions() {
const url = "/regions"
return fetch(url, {
method: "GET",
credentials: "include",
}).then(handleResponse).catch(handleError);
}
function getAddressStructure() {
return Promise.all([
GetCountries(),
GetCities(),
GetRegions()
])
.then((response) => {
return {
countries: response[0],
cities: response[1],
regions: response[2]
};
})
.catch((error) => {
return {
countries: response[],
cities: response[],
regions: response[]
}
});
}
// this is how you can use it:
getAddressStructure()
.then((response) => {
var apiResults = { };
apiResults = { ...response};
return resolve(apiResults);
})
What you want to achieve , you can use callback function to achieve these behavior without using promise.
async function getAddressStructure(country(args, getCities,getregioR)
{
var countries = await getCountries():
var cities= await getCities ():
var regions = await getRegion ();
return { countries : countries, cities: cities, regions: regions}
}
async function getCountries ();
async function getCities() {}
async function getRegion () {}
Related
const processInboundEmailAttachment = async (files: any[]): Promise<any[]> => {
const attachments = []
await Promise.all(
files.map(async (file) => {
try {
let response = null
response = await axios.get(file.url, {
headers: {
Accept: "message/rfc2822"
},
auth: {
username: "api",
password: "api-key"
},
responseType: "stream"
})
if (response && response.data) {
response.data.pipe(concat(async data => {
try {
const mediaUrl = await uploadToFirestore(file["content-type"], data, file.name)
attachments.push({
name: file.name,
url: mediaUrl,
id : uuidv4()
})
} catch (error) {
console.log("err", error);
}
}));
}
} catch (err) {
log.error(err)
}
})
)
return attachments // from here this return initial attachments [] array
}
const uploadAttachment = async () => {
const attachment = await processInboundEmailAttachment(JSON.parse(attach))
console.log("attachment",attachment);
// I want updated pushed attachment array here but I got [] initial decalare value
}
app.get("/uploadAttachment", uploadAttachment)
In attachment console log I got [] array , It's return initial assign values of array.
It's not wait for API response and newly pushed array.
I think There Is an some issue in Promise , It's not wait for updated array , It's
return directly initialy attachment array
Thank you for Help In advnace
Looks like it is not waiting for uploadFirestore response. You can cut down your function something like below and wrap it custom promise.
const processInboundEmailAttachment = async (files: any[]): Promise<any[]> => {
const getFileUploadedResult = function(file) {
return new Promise(async (resolve, reject) => {
try {
let response = null
response = await axios.get(file.url, {
headers: {
Accept: "message/rfc2822"
},
auth: {
username: "api",
password: "api-key"
},
responseType: "stream"
})
if (response && response.data) {
response.data.pipe(concat(async data => {
try {
const mediaUrl = await uploadToFirestore(file["content-type"], data, file.name)
resolve({
name: file.name,
url: mediaUrl,
id : uuidv4()
})
} catch (error) {
reject(err)
}
}));
}
} catch (err) {
log.error(err)
reject(err)
}
})
}
return Promise.all(
files.map(async (file) => {
return getFileUploadedResult(file)
})
)
}
const uploadAttachment = async () => {
const attachment = await processInboundEmailAttachment(JSON.parse(attach))
console.log("attachment",attachment);
// I want updated pushed attachment array here but I got [] initial decalare value
}
app.get("/uploadAttachment", uploadAttachment)
I'm having a problem with my API request that always fails after page load. Don't really know where Im wrong.
Here's my request and I call it when I interact with handleOpen function.
const stock = {
method: 'GET',
url: 'https://morningstar1.p.rapidapi.com/live-stocks/GetRawRealtimeFigures',
params: {Mic: props.mic, Ticker: clickedElement.ticker},
headers: {
'x-rapidapi-key': 'XXX',
'x-rapidapi-host': 'morningstar1.p.rapidapi.com'
}
}
const getStock = async () => {
try {
const res = await axios.request(stock);
return res.data;
}
catch (error) {
setOpen(false);
console.error("catch api error: ", error);
}
}
const handleOpen = name => {
let findClickedStock = props.stocksArray.find(item => item.ticker === name)
setClickedElement(findClickedStock)
getStock().then((dataFromStockApi) => {
let combined1 = { ...dataFromStockApi, ...findClickedStock }
setStockObject(combined1);
});
setOpen(true);
};
ERROR:
It's because your Ticker parameter is empty.
When you create "stock", clickedElement.ticker is undefined.
Do this:
// pass name in as a parameter
getStock(name).then(...)
Make getStock like like this:
const getStock = async (ticker) => {
try {
const res = await axios.request({
method: 'GET',
url: 'https://morningstar1.p.rapidapi.com/live-stocks/GetRawRealtimeFigures',
params: {Mic: props.mic, Ticker: ticker},
headers: {
'x-rapidapi-key': 'XXX',
'x-rapidapi-host': 'morningstar1.p.rapidapi.com'
}
});
return res.data;
}
catch (error) {
setOpen(false);
console.error("catch api error: ", error);
}
}
I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:
TypeError: Cannot read property 'json' of undefined
Corresponding with this line code:
const data = await res.json();
This is the complete file with the code:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data Json: ", data);
return { props: { data } };
};
This is the Json API response that I see by console:
{
account: [
{
id: '7051321',
type: 'probe',
status: 'open',
newAccount: [Object],
lastDate: '2020-07-04',
taxExcluded: [Object],
totalRecover: [Object],
documentLinks: []
},
]
}
Any idea how can I solve it?
Thanks in advance.
UPDATE
Here the code working good:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try {
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data JSON: ", data);
return { props: { data } };
} catch (error) {
console.log("Data ERROR: ", error);
}
};
There are a couple of things you have to change.
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
return response; // 1. Add this line. You need to return the response.
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const data = await getFetch(invoicesUrl, params);
// const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
console.log("Data Json: ", data); // Make sure this prints the data.
return { props: { data } };
};
You have return statement in wrong place.
When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try{
const res = await getFetch(invoicesUrl, params);
console.log("Data Json: ", res);
}catch(error){
console.log("Data Json: ", error);
}
return { props: { res } };
};
I am trying to test my REST APIs using Mocha and Chai.
Below is code snippet
"use strict"
// all required varibles modules declaration
describe("Get Data", function () {
it("Get Final Data", function () {
return getFinalResponse(
"https://localhost/getdata",
"GET",
JSON.stringify(rawdata)
)
.then((response) => response)
.then(async (response) => {
console.log(response)
let jsonData = await response.json()
operationId = jsonData.operation
console.log(jsonData.operation)
})
})
})
function delay(t) {
return new Promise((resolve) => setTimeout(resolve, t))
}
async function restCall(url, method, data) {
const signer = new common.DefaultRequestSigner(provider)
const httpRequest = {
uri: url,
headers: new Headers(),
method: method,
body: data,
}
await signer.signHttpRequest(httpRequest)
const response = await fetch(
new Request(httpRequest.uri, {
method: httpRequest.method,
headers: httpRequest.headers,
body: httpRequest.body,
})
)
return response
}
async function getFinalResponse(url, method, data) {
let response
do {
await delay(10000)
response = await restCall(url + "/done", method, data)
} while ((await response.json()["status"]) !== "DONE")
return restCall(url, method)
}
The condition while(await response.json()["status"] !== 'DONE') breaks/terminates in 1 minutes but even after putting 2 minutes as mocha time out . I am not getting the expected output.
Kindly help me what might be the issue.
I am new to react native and making service call for the first time. My problem is service call is not going and getting warning like
Possible unhandled Promise Rejection, Reference error: response is not defined.
I am trying to hit loginUser function.
Api.js
const BASE_URL = "http://localhost:8200";
export const api = async (url, method, body = null, headers = {}) => {
try {
const endPoint = BASE_URL.concat(url);
const reqBody = body ? JSON.stringify(body) : null;
const fetchParams = {method, headers};
if((method === "POST" || method === "PUT") && !reqBody) {
throw new Error("Request body required");
}
if(reqBody) {
console.log("ReQBody--->"+reqBody);
fetchParams.headers["Content-type"] = "application/json";
fetchParams.body = reqBody;
}
const fetchPromise = await fetch(endPoint, fetchParams);
const timeOutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("Request Timeout");
}, 3000);
});
const response = await Promise.race([fetchPromise, timeOutPromise]);
return response;
} catch (e) {
return e;
}
}
export const fetchApi = async (url, method, body, statusCode, token = null, loader = false) => {
console.log("In FetchAPi Function");
try {
const headers = {}
const result = {
token: null,
success: false,
responseBody: null
};
if(token) {
headers["securityKey"] = token;
}
const response = await api(url, method, body, headers);
console.log("fetchApi-->>"+response);
if(response.status === statusCode) {
result.success = true;
let responseBody;
const responseText = await response.text();
try {
responseBody = JSON.parse(responseText);
} catch (e) {
responseBody = responseText;
}
result.responseBody = responseBody;
return result;
}
let errorBody;
const errorText = await response.text();
try {
errorBody = JSON.parse(errorText);
} catch (e) {
errorBody = errorText;
}
result.responseBody = errorBody;
console.log("FetchApi(Result)--->>"+result);
throw result;
} catch (error) {
return error;
}
}
auth.actions.js
export const loginUser = (payload) => {
console.log("In LoginUser function2");
return async (dispatch) => {
<-----**I am not able to enter into this block**------>
try {
dispatch({
type: "LOGIN_USER_LOADING"
});
console.log("In LoginUser function3");
const response = await fetchApi("/login", "POST", payload, 200);
if(response.success) {
dispatch({
type: "LOGIN_USER_SUCCESS",
});
dispatch({
type: "AUTH_USER_SUCCESS",
token: response.token
});
dispatch({
type: "GET_USER_SUCCESS",
payload: response.responseBody
});
return response;
} else {
throw response;
}
} catch (error) {
dispatch({
type: "LOGIN_USER_FAIL",
payload: error.responseBody
});
return error;
}
}
}
In console log, I can't see anything in network tab. In the android emulator, the mentioned warning has come.
My console tab
I see that your BASE_URL is served using an http endpoint. You can only make requests to https endpoints from react native projects. A possible workaround is to use ngrok. Just download it and run ./ngrok http 8200 since your port number is 8200. It will expose an HTTPS endpoint and replace your BASE_URL with that link and try fetching the data again.
I use the following code to make API calls. See if you can integrate it in your code. it is quite simple:
In a class called FetchService:
class FetchService {
adminAuth(cb, data) {
console.log('here in the fetch service');
return fetch(
baseURL + "login",
{
method: "POST",
headers: {
Accept: "application/json",
},
body: data
}
)
.then((response) => response.json())
.then(responsej => {
cb(null, responsej);
})
.catch(error => {
cb(error, null);
});
}
}
export default FetchService;
Then call it from your component using:
import FetchService from './FetchService';
const fetcher = new FetchService;
export default class LoginScreen extends React.Component {
fetchData() {
const data = new FormData();
data.append('username',this.state.username);
data.append('password',this.state.password);
fetcher.wastereport((err, responsej) => {
if(err) {
//handle error here
} else {
//handle response here
}
}, data);
}
}