Pass query parameters to Snipcart API url inside a Netlify function - javascript

I’m trying to get JSON product data from Snipcart by querying my Netlify function as below:
const fetch = require("isomorphic-fetch");
const {SNIPCART_PRIVATE_KEY} = process.env;
const API_ENDPOINT = "https://app.snipcart.com/api/products";
const {snipcartID} = event.queryStringParameters;
const callAPI = async (event, context) => {
const auth =
'Basic ' +
Buffer.from(SNIPCART_PRIVATE_KEY + ':' + '').toString('base64');
const t = await fetch(API_ENDPOINT + "?userDefinedId=" + ${snipcartID || 'ABC'}, {
headers: {
Authorization: auth,
Accept: "application/json",
},
})
.then((response) => response.json())
.then(data => {
var results;
if (data) {
const {items} = data;
if (items) {
return {
name: items[0].name,
sales: items[0].statistics.numberOfSales,
};
}
}
return results;
})
.catch((error) => ({ statusCode: 422, body: String(error) }));
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: JSON.stringify(t),
};
};
exports.handler = callAPI;
I get the correct JSON data when I hard-code SNIPCART_ID in the function above. But I can’t pass my Snipcart id as a parameter using my page’s JavaScript as follows:
<script>
document.addEventListener("click", function (event) {
if (!event.target.matches("#collapsible")) return;
let URL = "/.netlify/functions/snipcart-getsales";
fetch(URL, "ABC")
.then((response) => response.json())
.then((data) => renderSales(data))
.catch(() => renderError());
});
function renderSales(data) {
const name = document.getElementById("name");
const sales = document.getElementById("sales");
const error = document.getElementById("error");
error.innerHTML = "";
name.innerHTML = data.name;
sales.innerHTML = data.sales;
}
function renderError() {
const error = document.getElementById("error");
error.innerHTML = "Whoops, something went wrong. Please try again later!";
}
</script>
What am I doing wrong here?

Can you console.log(event) before sending the request, to check if your function got the correct SNIPCART_ID that is send to the request.

I figured it out after some fiddling around :)
const fetch = require("isomorphic-fetch");
const {SNIPCART_PRIVATE_KEY} = process.env;
const API_ENDPOINT = "https://app.snipcart.com/api/products";
const callAPI = async (event, context) => {
const auth =
'Basic ' +
Buffer.from(SNIPCART_PRIVATE_KEY + ':' + '').toString('base64');
const querystring = event.queryStringParameters;
const userDefinedId = querystring.userDefinedId || 'ABC';
const t = await fetch(API_ENDPOINT + "?userDefinedId=" + userDefinedId, {
headers: {
Authorization: auth,
Accept: "application/json",
},
})
.then((response) => response.json())
.then(data => {
var results;
if (data) {
const {items} = data;
if (items) {
return {
name: items[0].name,
sales: items[0].statistics.numberOfSales,
};
}
}
return results;
})
.catch((error) => ({ statusCode: 422, body: String(error) }));
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: JSON.stringify(t),
};
};
exports.handler = callAPI;

Related

Passing argument to async / await function returns "undefined"

When posting data to an API and get a response, if I hardcode the body data inside the fetch call (body: "XYZ12345") it works fine, this is an example:
const vatValidationRequest =
fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: "XYZ12345",
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
const validateVAT = async () => {
const viesResponse = await vatValidationRequest;
console.log(viesResponse);
};
validateVAT();
However, if I try to pass the body data as an argument (body: vatNumber), the validateVAT() function returns "undefined". This is what's not working:
const vatValidationRequest = (vatNumber) => {
fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: vatNumber,
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
}
const validateVAT = async (vatNumber) => {
const viesResponse = await vatValidationRequest(vatNumber);
console.log(viesResponse);
};
validateVAT("XYZ12345");
Any clues about how to pass the argument to the async function? thanks!
The problem is that you are not returning the response from the method. You should do this:
const vatValidationRequest = (vatNumber) => {
return fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: vatNumber,
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
}
const validateVAT = async (vatNumber) => {
const viesResponse = await vatValidationRequest(vatNumber);
console.log(viesResponse);
};
validateVAT("XYZ12345");

I cannot call an API inside for loop using nodejs

I'm trying to call an API inside a for loop using Nodejs,when the code is executed only the last element is called by the API:
the code :
var array=[12,124,852,256,5677,256,5679,2546,567,28,574]
for(var i=0;i<array.length;i=i++){
var b = array.splice(i,3);
const parameters1 = {
Ids: b.toString(),
limit: 45,
}
const get_request_args1 = querystring.stringify(parameters1);
const options1 = {
method: 'GET',
host: "host",
port: '443',
path: path + '?' + get_request_args1,
headers: {
'Accept': 'application/json',
'authorization': `Bearer ${token}`,
'Accept-Encoding': 'identity',
}
}
var req = http.request(options1, (res) => {
context.log("API CALL...",i);
var body = "";
var pages = 0;
var offset = [];
var limit = 100000;
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
const obj = JSON.parse(body);
//context.log('total pages 3 :', pages);
context.log('total :', obj.total);
context.res = { body: offset };
context.done();
});
}).on("error", (error) => {
context.log('ERROR :', error);
context.res = {
status: 500,
body: error
};
context.done();
});
}
when this code is executed only the last element in the array executed by the API, what I'm looking for is executing the api for each iteration of the for loop, any helps please ?
Not sure how your full function looks like, but you should build your function as fully structured as async-await.
And also you could use map function instead of for.
const yourFunction = async () => {
try {
const array = [12,124,852,256,5677,256,5679,2546,567,28,574];
const requests = array.map(async (item) => {
...
var req = await http.request(async options1, (res) => {
context.log("API CALL...",i);
...
});
await Promise.all(requests);
...
} catch (err) {
console.error(err);
}
}

calling variable outside the function

I'm trying to develop a web page that get the data from another web application using axios.get and I wanna insert this data into the Postgres database, the problem is data is inside the then promise, I can not access it to insert it to the database, how can I do that or how can I access the data outside the then
I wanna insert var rn0 ty0
this is the main.js
const axios = require('axios')
const InsertToDataBase = require("./InsertToDataBase");
const username = 'admin'
const password = 'admin'
const token = Buffer.from(`${username}:${password}`, 'utf8').toString('base64')
const urlLAMP_0 = 'http://127.0.0.1:8282/~/mn-cse/mn-name/LAMP_0/DATA/la'
const urlLAMP_1 = 'http://localhost:8282/~/mn-cse/mn-name/LAMP_1/DATA/la'
function getDataLAMP_0(){
axios.get(urlLAMP_0, {
headers: {
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Origin':'*',
"X-M2M-RI":"OM2M-webpage",
'Authorization': `Basic ${token}`,
'Accept': 'application/json',
'mode': 'cors',
'credentials': 'include',
}
})
.then(function(response) {
document.getElementById("rn0").textContent = response.data['m2m:cin'].rn;
var rn0 = response.data['m2m:cin'].rn;
document.getElementById("ty0").textContent = response.data['m2m:cin'].ty;
var ty0 = response.data['m2m:cin'].ty;
document.getElementById("ri0").textContent = response.data['m2m:cin'].ri;
document.getElementById("pi0").textContent = response.data['m2m:cin'].pi;
document.getElementById("ct0").textContent = response.data['m2m:cin'].ct;
document.getElementById("lt0").textContent = response.data['m2m:cin'].lt;
document.getElementById("st0").textContent = response.data['m2m:cin'].st;
document.getElementById("cnf0").textContent = response.data['m2m:cin'].cnf;
document.getElementById("cs0").textContent = response.data['m2m:cin'].cs;
document.getElementById("con0").textContent = response.data['m2m:cin'].con;
})
}
getDataLAMP_0();
InsertToDataBase.insertdatatolamp0(rn0,ty0);
this is the InsertToDataBase.js
const {Client} = require('pg')
const client = new Client({
user:"postgres",
password:"admin",
host:"localhost",
port:"5432",
database:"postgres",
})
function insertdatatolamp0(rn0,ty0){
client.connect()
.then(()=>console.log("connected successfuly"))
.then(()=>client.query("insert into lamp0 values ($1,$2)",[rn0,ty0]))
.catch(e=> console.log(e))
.finally(()=> client.end())
}
module.exports = { insertdatatolamp0 };
You can chain promises. This will give you enough flexibility to do a series of actions one after the other, in your case change textContent and then insert some values into the database.
const axios = require("axios");
const InsertToDataBase = require("./InsertToDataBase");
const username = "admin";
const password = "admin";
const token = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
const urlLAMP_0 = "http://127.0.0.1:8282/~/mn-cse/mn-name/LAMP_0/DATA/la";
const urlLAMP_1 = "http://localhost:8282/~/mn-cse/mn-name/LAMP_1/DATA/la";
function getDataLAMP_0() {
axios
.get(urlLAMP_0, {
headers: {
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Origin": "*",
"X-M2M-RI": "OM2M-webpage",
Authorization: `Basic ${token}`,
Accept: "application/json",
mode: "cors",
credentials: "include",
},
})
.then(function (response) {
document.getElementById("rn0").textContent = response.data["m2m:cin"].rn;
document.getElementById("ty0").textContent = response.data["m2m:cin"].ty;
document.getElementById("ri0").textContent = response.data["m2m:cin"].ri;
document.getElementById("pi0").textContent = response.data["m2m:cin"].pi;
document.getElementById("ct0").textContent = response.data["m2m:cin"].ct;
document.getElementById("lt0").textContent = response.data["m2m:cin"].lt;
document.getElementById("st0").textContent = response.data["m2m:cin"].st;
document.getElementById("cnf0").textContent =
response.data["m2m:cin"].cnf;
document.getElementById("cs0").textContent = response.data["m2m:cin"].cs;
document.getElementById("con0").textContent =
response.data["m2m:cin"].con;
return response;
})
.then((response) => {
var rn0 = response.data["m2m:cin"].rn;
var ty0 = response.data["m2m:cin"].ty;
InsertToDataBase.insertdatatolamp0(rn0,ty0);
});
}
getDataLAMP_0();
You can do this with the help of Promise, here is a simple example
async function httpGetDataHandler() {
const url = "https://jsonplaceholder.typicode.com/posts";
const response = await fetch(url);
const parsedJson = await response.json();
const data = await parsedJson;
return Promise.resolve(data);
}
const getDataLAMP_0 = () => {
httpGetDataHandler()
.then((data) => {
// do your document.getElementById stuff in here
// I'm just returning the first index value, you can do whatever you want like return rn0
return data[0]
})
.then((data) => {
console.log("insert to database: ", data);
});
};
getDataLAMP_0();

res.json is not a function - nodejs

I've got this error using res.json to get the return of my function and this is code is been used em anothers places as wrote below, running fine.
async function getPlaylist(req, res, playlistId) {
try {
// const calltoken = await getToken()
// const token = calltoken.data.access_token
// console.log(token)
const config = {
headers: {
'Authorization': 'Bearer ' + 'BQA0K9bKgBVn8xTp-yTsoaKs5VfS7EyjMIL03OEOy05wq08ZmLkNfqbbnsL_hFT1AV2FGN5tAQdeDV1X224', //token,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
const url = 'https://api.spotify.com/v1/playlists/1j2L3DjzZ3SdN64r83Sblj?si=cuvOrPONSO6caE9XD6smEg'
await axios.get(url, config)
.then(function (response) {
var playlist = response
var items = playlist.data.tracks.items
// console.log(items)
const playlistfull = []
items.forEach(index => {
var playlistdata = {
name: index.track.name,
artists: index.track.album.artists[0].name,
album: index.track.album.name,
url: index.track.external_urls.spotify
}
playlistfull.push(playlistdata)
})
return res.json(playlistfull)
})
} catch (error) {
return console.log(error)
}
}
You have to use in NodeJS
Node's res give parameter to function
const router = express.Router();
router
.route('/')
.get((req, res) => {
const playlistId = 'asdf';
getPlaylist(req, res, playlistId);
return;
});

API Fetch update only one data

How can I update only one data through API? I want to change from status: 4 to status: 5
Here's my code
export const cancelRequest = async id => {
const response = await fetch(`API_URL/link/link/${id}`, {
method: 'put',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Auth.getToken()}`,
},
});
return getData(response);
};
Calling it through another file
const onCancelRequest = async id => {
let cancelItem = dataAll.filter(item => item.id == id);
await TriggerRequestAPI.cancelRequest(id)
.then(data => {
data.json();
cancelItem[0].status = 5;
setIsAll(cancelItem);
})
.catch(error => console.log(error));
};
You need to update your item first then call the API:
const onCancelRequest = async id => {
const cancelItems = dataAll.filter(item => item.id == id);
if(cancelItems.length === 0) {
return;
}
// Update the item
cancelItems[0].status = 5;
// Then call the API
await TriggerRequestAPI.cancelRequest(id, cancelItems[0])
.then(data => {
return data.json();
})
.then(item => {
setIsAll(cancelItems);
})
.catch(error => console.log(error));
};
API:
export const cancelRequest = async(id, item) => {
const response = await fetch(`API_URL/link/link/${id}`, {
method: 'put',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Auth.getToken()}`,
},
body: JSON.stringify(item) // item to update
});
return getData(response);
};

Categories

Resources