I am trying to create a new product by calling the shopify product api (/admin/api/2020-01/products.json). I am trying to achieve this using the "https" module. Below is the sample code
const url1 = 'https://{api_token}#tuscstore.myshopify.com/admin/api/2020-01/products.json';
var obj = {
"product":[
{
"title": "Saturn",
"body_html": "<p>The epitome of elegance</p>",
"vendor": "Soltions inc",
"product_type": "Planets",
"handle": "saturn",
"tags": "",
"images": [
{
"src": "https://solarsystem.nasa.gov/system/stellar_items/image_files/38_saturn_1600x900.jpg"
}
]
}
]
};
const https = require('https');
var data = JSON.stringify(obj)
const options = new URL(url1);
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
/* res.on('data', (d) => {
process.stdout.write(d);
}); */
});
req.on('error', (e) => {
console.error(e);
});
req.write(data);
req.end();
const Index = () => (
<div>
<p>Sample app using React and Next.js</p>
</div>
);
export default Index;
I am facing 2 problems,
when I do "process.stdout.write(d)", I receive cannot readproperty "write" undefined.
If I comment it out as I have done in
the code above, I don't get the error.
In either case I get the statuscode as 200, and not 201 which is what I shoudl receive according to shopify's docs.
Can someone please help me with what is going wrong?
Edit: Using Post,I get a type error
const https = require('https');
var data = JSON.stringify(obj)
var options = {
hostname: 'https://{apikey:password}#tuscstore.myshopify.com/admin/api/2020-01',
path: '/products.json',
method: 'POST',
headers: {
'Content-Type': 'application/json',
/*'Content-Length': data.length*/
'Authorization' : 'API_TOKEN'
}
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
});
req.on('error', (e) => {
console.error(e);
});
req.write(data);
req.end();
TypeError: Failed to execute 'fetch' on 'Window': Failed to parse URL from https://[https://{APIKEY:PWD}#tuscstore.myshopify.com/admin/api/2020-01]/products.json
you creating a new product you have to make http POST request , and now your making http GET request you should update your options like so :
const options = {
hostname: 'https://apikey:password#<#store_url>/admin/api/2020-01', // your host name
path: '/shop.json', // your end point
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization' : 'YOUR_API_TOKEN'
}
}
OR you can use this package to solve all your problems https://www.npmjs.com/package/shopify-api-node
Related
this is my code where am using http module to call the api inside the promise but not able make
any api call its just giving 500 err
const dataString = JSON.stringify(consentDetail)
console.log("dataString",dataString)
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': dataString.length
}
}
const response = await new Promise((resolve, reject) => {
const req = https.get("URL", options, (res) => {
let finalData = "";
res.on("data", function(data){
finalData += data.toString();
})
res.on("end", () => {
var data = JSON.parse(finalData);
resolve({
statusCode: 200,
body: JSON.stringify(data, null, 2)
})
})
})
req.on('error', (err) => {
reject({
statusCode: 500,
body: err
});
})
})
return response;
and I want call the api using only http or https without having to install any npm package
There are a few things you will need to change in your code. First, the API you are calling is expecting a GET request, so you have to change that in your 'options' object. And since you're going to send a GET request, the headers 'Content-Type' and 'Content-Length' need to be removed.
Also, there is no 'url' option for the 'options' in the http module. This is why you are receiving a 500 response. Since no url/host were provided to the http module, it is attempting to connect to http://127.0.0.1:80. The correct way is to use the parameters 'host' and 'path', like this:
const options = {
host: 'catfact.ninja',
path: '/fact',
method: 'GET'
}
or include the url as the first parameter in the get method, like this:
const req = http.get('http://catfact.ninja/fact', options, (res) => {
...
}
By doing so, you will see that we now receive a new error:
undefined:1
<html>
^
SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (C:\...\index.js:18:33)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
The reason for this is that we are receiving a html response instead of a JSON. Looking further into the response, we can see that we actually received a 301 response:
HTTP/1.1 301 Moved Permanently
Server: nginx/1.20.1
Date: Wed, 29 Dec 2021 19:24:33 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://catfact.ninja/fact
The 301 redirects to the https protocol, meaning the API doesn't support http requests anymore. So let's use https instead. Just use the https built-in module instead of the http one, and change the URL to https://catfact.ninja/fact. No other changes to the code are necessary.
So, the final code should be:
const options = {
method: 'GET'
}
const response = await new Promise((resolve, reject) => {
const req = https.get('https://catfact.ninja/fact', options, (res) => {
let finalData = "";
res.on("data", function(data){
finalData += data.toString();
})
res.on("end", () => {
var data = JSON.parse(finalData);
resolve({
statusCode: 200,
body: JSON.stringify(data, null, 2)
})
})
})
req.on('error', (err) => {
reject({
statusCode: 500,
body: err
});
})
})
return response;
I think you should use https.request and options pass host and path.
check here:
https://nodejs.org/api/https.html#httpsrequestoptions-callback
const dataString = JSON.stringify(consentDetail);
console.log("dataString", dataString);
const options = {
// Update here
hostname: "hostname",
path: "/path",
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": dataString.length,
},
};
const response = await new Promise((resolve, reject) => {
// update here
const req = https.request(options, (res) => {
let finalData = "";
res.on("data", function (data) {
finalData += data.toString();
});
res.on("end", () => {
var data = JSON.parse(finalData);
resolve({
statusCode: 200,
body: JSON.stringify(data),
});
});
});
req.on("error", (err) => {
reject({
statusCode: 500,
body: err,
});
});
});
return response;
I am working on a little project to learn how to work with APIs by making GET requests to the Twitter API v2 via a node server.
For the get requests I am using Node's built in https package.
I made a basic GET request that returns a list of the last 10 tweets from a user.
I think in order to increase the amount of tweets I can get I have to make a separate parameter object, which I then implement in the get request.
Right now my function looks like this:
function getTweets() {
const options = {
host: "api.twitter.com",
path: `/2/users/${userId}/tweets`,
headers: {
authorization:
`Bearer ${bearerToken}`,
},
};
https
.get(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
let jsonObject = JSON.parse(data);
tweetObjects = jsonObject.data;
tweetObjects.map((item) => {
let tweetWords = "";
tweetWords += item.text;
userTweets.push(tweetWords);
});
const result = userTweets.flatMap((str) => str.split(" "));
console.log(result);
});
})
.on("error", (error) => {
console.log(error);
});
}
Right now I only have the options object with host, path, and headers in the request.
This is what I am trying to do:
function getTweets() {
const options = {
host: "api.twitter.com",
path: `/2/users/${userId}/tweets`,
headers: {
authorization:
`Bearer ${bearerToken}`,
},
};
let params = {
max_results: 100,
};
https
.get(params, options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
let jsonObject = JSON.parse(data);
tweetObjects = jsonObject.data;
tweetObjects.map((item) => {
let tweetWords = "";
tweetWords += item.text;
userTweets.push(tweetWords);
});
const result = userTweets.flatMap((str) => str.split(" "));
console.log(result);
});
})
.on("error", (error) => {
console.log(error);
});
}
But I get
throw new ERR_INVALID_ARG_TYPE('listener', 'Function', listener);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object
at checkListener (events.js:131:11)
at ClientRequest.once (events.js:496:3)
at new ClientRequest (_http_client.js:215:10)
at request (https.js:326:10)
at Object.get (https.js:330:15)
at IncomingMessage.emit (events.js:388:22)
at endReadableNT (internal/streams/readable.js:1336:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
code: 'ERR_INVALID_ARG_TYPE'
You can either only pass the URL or an object containing options as stated in the docs:
https://nodejs.org/api/https.html#https_https_get_url_options_callback
So you might want to try something like this:
function getTweets() {
let params = {
max_results: 100,
};
const options = {
host: "api.twitter.com",
path: `/2/users/${userId}/tweets?max_results=${params.max_results}`,
headers: {
authorization:
`Bearer ${bearerToken}`,
},
};
https
.get(options, (response) => {
let data = "";
...
}
I am not sure to understand what you are calling parameters that you want to give to the get request.
Anyway a get request does not take some body or parameter. If you want to add some data to the core of your request you have to use the post method and not the get one.
Can you show us the import of https library just to check the functions that it propose?
Best Regards,
Hugo Delatte
I am new in Node/Express and I would like to get some help with the following situation. I want to create a function that will execute when calling an API endpoint which will return a list of addresses from another API that is already working. I was following some code I found in the tutorials and when calling the function in Postman as an endpoint, it returns the data in the terminal but I want the data to be return in postman.
getAddress() {
let result=[];
const address = JSON.stringify({
number: "1234",
street: "Main St",
city: "Newark",
state: "NJFL",
zipCode: "01234",
});
const https = require("https");
const options = {
hostname: "thisiaurl",
port: 8001,
path: "/address",
method: "POST",
json: address,
headers: {
"Content-Type": "application/json",
},
}
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on("data", (d) => {
process.stdout.write(d);
});
});
req.on("error", (error) => {
console.error(error);
});
req.write(address);
req.end();
return result;
};
I am not sure how to modify this code in order to return the "result" with the list of addresses (response). Can you please help? Thanks
Can you please try
result = address;
Before
const https = require("https");
Line.
I am trying to access all the projects from Harvest API and parse it as a JSON file. But I am new to Node JS so I do not know where to begin. Here is the link to the API documentation: Harvest API Documentation
API requires all the calls to be authenticated how can I work around that?
Thank you in Advance
You can parse using JSON.parse(data) to get the JSON Object
const https = require("https");
const options = {
protocol: "https:",
hostname: "api.harvestapp.com",
path: "/v2/users/me",
headers: {
"User-Agent": "Node.js Harvest API Sample",
Authorization: "Bearer " + process.env.HARVEST_ACCESS_TOKEN,
"Harvest-Account-ID": process.env.HARVEST_ACCOUNT_ID,
},
};
https
.get(options, (res) => {
const { statusCode } = res;
if (statusCode !== 200) {
console.error(`Request failed with status: ${statusCode}`);
return;
}
res.setEncoding("utf8");
let rawData = "";
res.on("data", (chunk) => {
rawData += chunk;
});
res.on("end", () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
})
.on("error", (e) => {
console.error(`Got error: ${e.message}`);
});
Please refer
https://github.com/harvesthq/harvest_api_samples/blob/master/v2/harvest_api_sample.js
I'm trying to use the asana-api to create a Task using a POST http request but I keep getting a 400 bad request as a response.
I managed to get data from the Asana-api using ( a GET request ), but I'm having trouble sending data to Asana with ( a POST request )
I'm using the 'request' module to do the api call
here's the error message :
`{"errors":[{
"message":"Could not parse request data,invalid JSON",
"help":"For more information on API status codes and how to handle them,
read the docs on errors: https://asana.com/developers/documentation/getting-started/errors"}
]}`
Here's my code:
testTask(){
var taskName = "Test Name for a Test Task"
var workspaceID = "123456789"
var projectID = "123456789"
var assigneeID = "123456789"
var parentID = null
this.createTask(taskName, workspaceID, projectID, assigneeID, parentID)
}
createTask(taskName, workspaceID, projectID, assigneeID, parentID){
var token = "0/1234abcd5678efgh9102ijk"
var bearerToken = "Bearer " + token
var task = {
data: {
assignee: "me",
notes: "test test test test",
workspace: workspaceID,
name: taskName,
projects: [projectID],
parent: parentID
}
}
var options = {
"method" : "POST",
"headers" : {"Authorization": bearerToken},
"contentType": "application/json",
"payload" : JSON.stringify(task)
}
try {
var url = "https://app.asana.com/api/1.0/tasks";
request.post(url, options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
}
catch (e) {
console.log(e);
}
}
I also tried a different implementation :
createTask(){
var token = "0/1234abcd5678efgh9102ijk"
var bearerToken = "Bearer " + token
var options = {
"method" : "POST",
"headers" : {"Authorization": bearerToken},
}
try {
request.post("https://app.asana.com/api/1.0/tasks?workspace=1234567&projects=765534432&parent=null&name=taskName&assignee=me", options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
}
catch (e) {
console.log(e);
}
}
Based on the examples provided by the request module, it appears that your options object uses payload as a key, but it should be body.