Error: function uses multiple asynchronous interfaces: callback and promise - javascript

Error: function uses multiple asynchronous interfaces: callback and
promise
to use the callback interface: do not return a promise
to use the promise interface: remove the last argument to the function
I'm trying to write a cucumber test to one of my GET node API, and keep getting the above, looked at few GitHub and stack-overflow posts, and could not understand the issue, below are my test method details.
App.ts
async getSsoId(refId: any): Promise<string> {
let ssoId = '';
const secrets = await this.vaultService.getClientSecrets();
this.decrypt(refId, secrets.encryption_secret, secrets.encryption_Id).then((value: any) => {
ssoId = value;
});
return ssoId;
}
api.get('/status', async (req, res) => {
let id;
const statusCode = 200;
try {
id = await this.getId(String('123456'));
} catch (err: any) {
throw new ApiError('Error fetching id');
}
try {
const item = await dbService.getItem(id);
if (item) {
statusCode = 201;
} else {
statusCode = 202;
}
} catch (err: any) {
throw new ApiError(
'The API encountered an error while attempting to communicate with the DB service.'
);
}
res.status(statusCode).send(statusCode);
});
Step Definition:
Given('a valid customer', function () {});
When("I call the get-id api", { timeout: 2 * 5000 }, async function (val) {
util.callGetIdAPI().then((response) => {
this.setApiResponseStatus(response.status);
this.setResponseBody(JSON.stringify(response.body));
});
});
Then("the apiResponseStatus should be <apiResponseStatus>", function (status) {
assert.strictEqual(status, this.apiResponseStatus);
});
Then("the responseBody should be {string}", function (responseBody) {
assert.equal(responseBody, this.responseBody);
});
Util Function
callGetIdAPI = async () => {
const headers = {
'Content-Type': 'application/json;v=1',
Accept: 'application/json;v=1'
}
const client = await getClient('url');
const options = {
method: 'GET',
headers: headers,
version: 3
};
let response;
try {
response = await client.get('/status', options);
return {
status: response.statusCode,
body: response.body
};
} catch(error) {
return {
status: error.statusCode,
body: {
error: {
id: error.id,
message: error.message
}
}
}
}
};
I'm new to this and trying to understand how multiple Premisses and Callbacks works in parallel, any thoughts or inputs on what possibly cause the error, or am I missing anything ??

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);
}
});

Nest.JS and Observables

I am new to Nest.JS and apparently don't understand how to use observables so hopefully ya'll can help.
Basically I have a method that needs to:
first: login to hashicorp vault and return a client_token via an http call.
second: if we got a token back from vault, we then check that the request contained a certification-id, if not we have to request a new certification to be generated. Which requires the client_token from vault.
The problem I am having is that when I call vault to get the client_token, it does not get returned in time for me to be able to use it to generate a new cert via a second api call.
What can I do in order to be able to use the client_token in the next step?
Here is the code for my latest attempt:
Controller:
#Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
#Post('getUserCert')
async getUserCert(#Body() loginDto: vaultLoginReqDto) {
return this.userService.getCertificate(loginDto);
}
}
Controller calls the getCertificate method:
getCertificate(loginDto: vaultLoginReqDto) {
this.loginToVault(loginDto);
if (this.vault_token) {
if (loginDto.cert_id) {
this.checkForExistingCert(loginDto);
} else {
this.generateNewCert(this.vault_token);
}
} else {
throw new Error('User is not authorized to access Vault.');
}
}
The logon method:
loginToVault(loginDto: vaultLoginReqDto) {
const url = 'http://vault:8200/v1/auth/jwt/login';
const payload: vaultLoginReqDto = {
jwt: loginDto.jwt,
role: loginDto.role,
};
try {
this.httpService
.post(url, payload)
.subscribe((res: AxiosResponse<vaultLoginResDto>) => {
this.vault_token = res.data.auth.client_token;
});
} catch (e) {
this.throwError(e, url, 'Unable to login to vault');
}
}
the problem method is the generateNewCert method. It is not getting the vault_token in time.
generateNewCert(vault_token: string): Observable<string> {
const url = `http://127.0.0.1:8200/v1/xxxx/xxxx/issue/reader`;
const payload = {
common_name: 'id.xxxx.com',
};
const headers = {
'X-Vault-Token': vault_token,
};
try {
return this.httpService.post(url, payload, { headers: headers }).pipe(
map((res: AxiosResponse<vaultGetCertResDto>) => {
return res.data.data.certificate;
}),
);
} catch (e) {
this.throwError(e, url);
}
}
I appreciate the help!
The easiest way to make it work is the convert to a Promise so you can wait for the result.
loginToVault(loginDto: vaultLoginReqDto) {
const url = 'http://vault:8200/v1/auth/jwt/login';
const payload = {
jwt: loginDto.jwt,
role: loginDto.role,
};
return this.httpService
.post(url, payload)
.pipe(
catchError(() => {/** ...handleError **/}),
map((res) => {
this.vault_token = res.data.auth.client_token;
return this.vault_token;
}),
)
.toPromise()
}
Now, you can use async / await at getCertificate
async getCertificate(loginDto: vaultLoginReqDto) {
await this.loginToVault(loginDto);
// or const vault_token = await this.loginToVault(loginDto)
if (this.vault_token) {
if (loginDto.cert_id) {
this.checkForExistingCert(loginDto);
} else {
this.generateNewCert(this.vault_token);
}
} else {
throw new Error('User is not authorized to access Vault.');
}
}
If you decide to stick with the observables, you can return an observable from the loginToVault method as opposed to subscribing to it
loginToVault(loginDto: vaultLoginReqDto): Observable<string> {
const url = 'http://vault:8200/v1/auth/jwt/login';
const payload = {
jwt: loginDto.jwt,
role: loginDto.role,
};
return this.httpService
.post(url, payload)
.pipe(
catchError(() => { /* handle errors */ }),
map((res) => res.data.auth.client_token)
)
}
Then in getCertificate method, you subscribe to loginToVault and handle the logic
getCertificate(loginDto: vaultLoginReqDto) {
this.loginToVault(loginDto)
.pipe(
tap(vault_token => {
if (!vault_token) {
throw new Error('User is not authorized to access Vault.');
}
})
)
.subscribe(vault_token => loginDto.cert_id ?
this.checkForExistingCert(loginDto) :
this.generateNewCert(vault_token)
)
}
The vault_token is passed from one service to another and thus will be accessible in the generateNewCert method. You do not need to declare it globally

UnhandledPromiseRejectionWarning, how to fix it?

I don't know what I could be doing wrong to get this error:
I've tried different promises, await, async combinations and nothing.
I've tried Promise.resolve()) and also .then(function().
Nothing stopped that error, what can I change to fix it?
#Controller()
export class AppController {
constructor(private httpSoap: HttpClient,
#InjectModel('product') private readonly productModel: Model<any>,
private xmlUtils: XmlUtils) { }
#EventPattern("next")
async handleMessagePrinted(data: Record<any, any>) {
let result = data;
this.createproduct(result);
this.insertproduct(result);
}
insertproduct(data: any) {
stringify(data);
this.productModel.insertMany(data);
}
async createproduct(job: any): Promise<any> {
return new Promise((async (resolve, reject) => {
// if (this.soapService.productCreate) {
const payload = job;
const xmlPayload = this.xmlUtils.parseJSONtoXML(payload);
this.insertproduct(stringify(xmlPayload)); //gravar na mongo
console.log("xmlPayload "+xmlPayload);
const headerRequest = {
'Content-Type': ContentTypeEnum.XML,
SOAPAction: SoapActionEnum.CREATE_SERVICE_product
};
const soap: ResponseInterface = await this.request("localhost:8080", xmlPayload, headerRequest, SoapType.product);
if (soap.error) {
reject(soap.error);
}
if (soap.status) {
if (soap.status.firewall.code === '000-000' || soap.status.firewall.code === '000-001') {
resolve(`product ${soap.body.Number} created successfully`);
} else if (soap.status.firewall.code === '000-998' && soap.status.fireWall.code === '623') {
reject({ error: soap.status.fireWall.description });
} else if (soap.status.firewall.code === '000-500' && soap.status.fireWall.code === 'BWENGINE-100029') {
const payloadSearch: productSearchDocument = new productSearchDocument();
payloadSearch.IsOperational = undefined;
payloadSearch.IsHistory = undefined;
payloadSearch.Qualification = `id='${job.data.id_ID}'`;
const search = await this.searchproduct(payloadSearch);
if (search.status) {
if (search.status.firewall.code === '000-000' || search.status.firewall.code === '000-001') {
resolve(`product ${soap.body.Number} created successfully`);
}
} else {
reject({ error: search.status.firewall.description, fireWallError: soap.status.fireWall.description });
}
} else {
reject({ error: soap.status.firewall.description, fireWallError: soap.status.fireWall.description });
}
}
}));
}
public async searchproduct(data: any): Promise<any> {
return new Promise((async (resolve, reject) => {
// if (this.soapService.productSearch) {
const payload = data;
const xmlPayload = this.xmlUtils.parseJSONtoXML(payload);
const headerRequest = {
'Content-Type': ContentTypeEnum.XML,
SOAPAction: SoapActionEnum.SEARCH_SERVICE_product
};
const soap: ResponseInterface = await this.request("localhost:8080", xmlPayload, headerRequest, SoapType.product);
if (soap.error) {
reject(soap.error);
}
if (soap.status) {
if (soap.status.firewall.code === '000-000' || soap.status.firewall.code === '000-001') {
resolve(soap);
} else {
reject({ error: soap.status.fireWall.description });
}
} else {
reject({ error: soap });
}
}));
}
public request(uri: string, data: any, headers: IHeaders, type: SoapType): Promise<any> {
return new Promise(((resolve) => {
this.httpSoap.request(uri, data, (async (err, res) => {
if (err) {
resolve({ error: err });
} else {
try {
console.log("fireWall response: "+data);
const bodyJson = await this.xmlUtils.formatXmlToJson(res.body);
const status: StatusInterface = await this.xmlUtils.formatStatusXML(bodyJson);
let body;
if (type === SoapType.product) {
body = await this.xmlUtils.formatproductServiceBodyXml(bodyJson);
this.insertproduct(stringify(bodyJson)); //gravar na mongo
} else if (type === SoapType.UNAVAILABILITY) {
body = await this.xmlUtils.formatImpactServiceBodyToXML(bodyJson);
} else if (type === SoapType.TASK) {
body = await this.xmlUtils.formatTaskServiceBodyXML(bodyJson);
} else {
body = '';
}
const response: ResponseInterface = {
status,
body,
};
resolve(response);
} catch (e) {
resolve(e);
}
}
}), headers);
}));
}
public simpleRequest(connection, payload): Promise<any> {
return new Promise<any>((resolve, reject) => {
const headers = {
};
this.httpSoap.request("localhost:8080", payload, (async (err, res) => {
if (err) {
resolve({ error: err });
} else {
try {
if (res.statusCode === 500) {
// const bodyJson = await this.xmlUtils.formatXmlToJson(res.body);
resolve(res.body);
} else {
const bodyJson = await this.xmlUtils.formatXmlToJson(res.body);
resolve(bodyJson);
}
} catch (e) {
reject(e);
}
}
}), headers);
});
}
}
My goal is to be able to save to mongo and also be able to make the http call to the SOAP api
This warning is shown when you don't add a rejection handler to a Promise, and it's rejected. It can be rejected when an error is occurred inside a promise, or reject() is called.
reject called:
const aa = new Promise((resolve, reject) => {
reject(new Error('whoops'));
});
aa.then(v => {
console.log(v);
});
// Running this script gives unhandled rejection warning
an error is occurred:
const aa = new Promise((resolve, reject) => {
const a = {};
// "cannot read property 'unexistingProperty' of undefined" error is thrown here
const b = a.b.unexistingProperty;
// alternatively, when an is thrown with throw
// throw new Error('oops')
});
aa.then(v => {
console.log(v);
});
// Running this script also gives unhandled rejection warning
You can add a rejection handler via then (the second argument to then() is rejection handler) or catch. For async/await you can add a try/catch block to catch error.
In node.js you can also add rejection handler to all unhandled rejected promises with process.on('unhandledRejection') like this:
process.on('unhandledRejection', error => {
console.log(error);
});
You can also see where the error is thrown with unhandledRejection event handler shown above, or you can run node.js with --trace-warnings like this.
node --trace-warnings index.js
References:
https://thecodebarbarian.com/unhandled-promise-rejections-in-node.js.html
https://nodejs.org/dist/latest-v14.x/docs/api/process.html

AWS Lambda retries despite returning value

I have found out that my and my colleagues lambda doesn't return data we anticipate.
After what I have already found, we used deprecated invokeAsync which returnes only statusCode.
I have upgraded aws-sdk to the newest version and change the invocation code to use invoke with
InvocationType: 'RequestResponse'
as that should give us the returned value.
Lambdas code itself looks good, its an async function without arguments.
Im not using the callback here (3rd argument of handler), as we are doing some async stuff and it would require a small refactor to not use async/await, also i have read that just returning value is ok as well.
Earlier lambda was returning array, but after some investigation and googling I have changed it to
return {
statusCode: 200,
body: JSON.stringify(result)
}
where result is the mentioned array, as this was recurring pattern in search results.
Overall result is in our service where we do the invocation, we get timeout, lambda logs that it is returning value, but then retries itself again and again.
Dumping code
invocation in our service:
const lambda = new AWS.Lambda({ httpOptions: { timeout: 600000 } })
const results = await new Promise((resolve, reject) => {
lambda.invoke(
{
FunctionName: `lambda-name`,
InvocationType: 'RequestResponse',
Payload: '""'
},
(err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
}
)
})
lambda handler
import { parallelLimit } from 'async'
const PARALLEL_FETCHERS_NUMBER = 2
export async function runTasksInParallel (
tasks,
limit,
) {
return new Promise(
(
resolve,
reject,
) => {
parallelLimit(tasks, limit, (error, results) => {
if (error === null) {
resolve(results)
} else {
reject(error)
}
})
},
)
}
async function connectToDB(logger) {
const MONGO_URL = process.env.MONGO_URL || 'mongodb://localhost:27017/'
let db
logger.debug('Connecting to mongo')
try {
db = await MongoClient.connect(
MONGO_URL,
{
sslValidate: false,
}
)
} catch (error) {
logger.error('Could not connect to Mongo', { error })
throw error
}
logger.debug('Connected')
return db
}
async function fetchAndStore(
list,
sources,
logger
) {
const results = []
const tasks = sources.map((source) => async (callback) => {
const { fetchAdapter, storageAdapter } = source
try {
const { entries, timestamp } = await fetchAdapter.fetchLatest(list)
await storageAdapter.storeMany(timestamp, entries)
results.push(['fetch.success', 1, [ `fetcher:${fetchAdapter.name}` ] ])
} catch (error) {
const errorMessage = `Failed to fetch and store from adapter ${fetchAdapter.name}`
const { message, name, stack } = error
logger.error(errorMessage, { error: { message, name, stack } })
results.push(['fetch.error', 1, [ `fetcher:${fetchAdapter.name}` ] ])
}
callback && callback(null)
})
await runTasksInParallel(tasks, PARALLEL_FETCHERS_NUMBER)
return results
}
export async function handle() {
const logger = createLambdaLogger() // just a wrapper for console.log to match interface in service
logger.debug('Starting fetching data')
const db: Db = await connectToDB(logger)
const primaryCollection = db.collection(PRIMARY_COLLECTION)
const itemsColletion = db.collection(ITEMS_COLLECTION)
const secondaryCollection = db.collection(SECONDARY_PRICING_COLLECTION)
const primaryStorageAdapter = new StorageAdapter(
Promise.resolve(primaryCollection),
logger
)
const itemsStorageAdapter = new ItemsStorageAdapter(
Promise.resolve(itemsColletion),
logger
)
const secondaryStorageAdapter = new StorageAdapter(
Promise.resolve(secondaryCollection),
logger
)
const primaryFetchAdapter = new PrimaryFetchAdapter(getFetcherCredentials('PRIMARY'), logger)
const secondaryFetchAdapter = new SecondaryFetchAdapter(getFetcherCredentials('SECONDARY'), logger)
const sources = [
{ fetchAdapter: primaryFetchAdapter, storageAdapter: primaryStorageAdapter },
{ fetchAdapter: secondaryFetchAdapter, storageAdapter: secondaryStorageAdapter },
]
try {
const list = await itemsStorageAdapter.getItems()
logger.debug(`Total items to fetch ${list.length}`)
const result = await fetchAndStore(list, sources, logger)
logger.debug('Returning: ', { result })
return {
statusCode: 200,
body: JSON.stringify(result)
}
} catch (error) {
const errorMessage = 'failed to do task'
const { message, name, stack } = error
logger.error(errorMessage, { error: { message, name, stack } })
return {
statusCode: 500,
body: JSON.stringify(new Error(errorMessage))
}
} finally {
await db.close()
}
}
Edit:
I have changed the way i'm invoking the lambda to this below. Basically I tried to listen for every possible event that can say me something. Result is that i get a error event, with response message being Converting circular structure to JSON. Thing is I don't really know about which structure this is, as the value I'm returning is a two elements array of 3 elements (strings and number) arrays.
const lambda = new AWS.Lambda({
httpOptions: { timeout: 660000 },
maxRetries: 0
})
const request = lambda.invoke(
{
FunctionName: `${config.get('env')}-credit-rubric-pricing-fetching-lambda`,
InvocationType: 'RequestResponse',
Payload: '""'
},
(err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
}
)
const results = await request
.on('send', () => {
logger.debug('Request sent to lambda')
})
.on('retry', response => {
logger.debug('Retrying.', { response })
})
.on('extractError', response => {
logger.debug('ExtractError', { response })
})
.on('extractData', response => {
logger.debug('ExtractData', { response })
})
.on('error', response => {
logger.debug('error', { response })
})
.on('succes', response => {
logger.debug('success', { response })
})
.on('complete', response => {
logger.debug('complete', { response })
})
.on('httpHeaders', (statusCode, headers, response, statusMessage) => {
logger.debug('httpHeaders', { statusCode, headers, response, statusMessage })
})
.on('httpData', (chunk, response) => {
logger.debug('httpData', { response, chunk })
})
.on('httpError', (error, response) => {
logger.debug('httpError', { response, error })
})
.on('httpDone', response => {
logger.debug('httpDone', { response })
})
.promise()

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