I want to call to API, get json data and set it to resolvers Query in Graphql. So far I managed to working Graphql server and get call to API. This is my code so far
//resolvers.js
//var fetch = require('node-fetch');
var request = require("request");
var options = { method: 'GET',
url: 'http://mydomain.con/index.php/rest/V1/products/24-MB01',
headers:
{ 'postman-token': 'mytoken',
'cache-control': 'no-cache',
'content-type': 'application/json',
authorization: 'Bearer mytoken' } };
const links = request(options, function (error, response, body) {
if (error) throw new Error(error);
//body = json data
//console.log(body);
});
module.exports = {
Query: {
//set data to Query
allLinks: () => links,
},
};
I dont know how to set the body parameter which contain json data to Query. I have also same data on "http://localhost/src/apicall.php" but this is not working with node-fetch (or Im making mistakes). Api is from magento2.
You were close !
What you are doing right now is sending the links request right when your application starts. You don't want that ; you want to send the request when the allLinks field is requested in GraphQL.
So what you need is to have in the allLinks field a function making the request to your API, and returning the response.
If you return a Promise within the allLinks field, it will wait upon completion to use the returned value as an answer.
So, putting it all together:
...
const getAllLinks = () => {
return new Promise((resolve, reject) => {
request(options, function (error, response, body) {
if (error) reject(error);
else resolve(body);
});
});
};
module.exports = {
Query: {
//set data to Query
allLinks: getAllLinks,
},
};
Related
I am using express with js to delete a record from my azure sql database (prisma is the orm). The post method worked on the leads route. The delete did not work...it is posting empty record to Leads table rather than triggering the delete function on the server side:
--Client Side Script
document.querySelector('#delete_leads_form').addEventListener('submit', function(e){
e.preventDefault();
const inputs = document.querySelectorAll('#delete_leads_form input, #delete_leads_form select')
const payload = {};
inputs.forEach(input=>{
payload[input.name] = input.value
})
async function deleteReq(){
try {
const response = await fetch('https://hh-events-internal.herokuapp.com/lead', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(payload)
} )
const responseJson = await response.json()
console.log('response', responseJson)
} catch (error) {
console.error(error)
}
}
deleteReq()
})
I have tried changing the client side method to DELETE, and no luck.
I've built an API using C# that uses JWT tokens for authorization. On the frontend I store these tokens in local storage and get them, when creating a request. When creating GET or DELETE requests, everything works fine, and using console.log() I can see that fetch options have the Authorization header added. However when using POST or PATCH methods, the Authorization header is missing immediatly after adding it to the object. Here is my request method:
const send = async (apiOptions: ApiParams): Promise<FetchReturn> => {
const accessToken = GetAccessToken()
const options: ApiOptions = {
method: apiOptions.method,
headers: {
Authorization: `Bearer ${accessToken}`
}
}
console.log(options)
if (apiOptions.data) {
options.headers = {
'Content-Type': 'application/json'
}
options.body = JSON.stringify(apiOptions.data)
}
const result = await fetch(`${getUrl()}/${apiOptions.path}`, options).then(res => res).catch(err => err)
if (!result.ok) {
if (IsExpired()) {
const refreshResult = await fetch(`${getUrl()}/api/user/refresh`, {method: 'POST', headers:{
'Content-Type': 'application/json'
}, body: JSON.stringify(GetRefreshRequest())}).then(res => res).catch(err => err)
if (refreshResult.ok) {
Login(JSON.parse(await refreshResult.text()))
return await send(apiOptions)
} else if (refreshResult.status === 401) {
Logout()
window.location.reload()
return { code: 0, text: ""}
}
}
}
const text = await result.text()
return { code: result.status, text: text }
}
I suppose that in apiParams for POST you have property 'data' assigned, and later you have if-condition that completely replaces request headers object.
Change it to:
options.headers['Content-Type'] = 'application/json';
To keep authorization in headers
The first time check your apiOptions.data
i think , its null when you call POST/Patch request
Just put console.log("...") In the if statement , Then try for resolve your Error
If your problem not resolved, put a replay under my post
I am working on the Zoom API now. I want to send my token from ZOOM API to front-end as a response. However, "token from request" is always printed first and undefined! Then the token from Zoon API" will be followed with the token. How can I make it happen? Thx!
const Newrequest = require("request");
class ZoomController {
async getInvLink({ request, response }) {
const instructor_id = params.id;
try {
let tokenRes;
const code = request.all().code;
console.log("the code from frontend is ", code);
const client_id = _something_
const client_secret = _something_
var options = {
method: "POST",
url: "https://api.zoom.us/oauth/token",
qs: {
grant_type: "authorization_code",
code: code,
redirect_uri: _something_
},
headers: {
Authorization:
"Basic " +
Buffer.from(client_id + ":" + client_secret).toString("base64")
}
};
await Newrequest(options, function(error, res, body) {
if (error) throw new Error(error);
tokenRes = JSON.parse(body);
console.log("token from Zoon API",tokenRes);
});
console.log("token from request",tokenRes);
return response.status(200).send(tokenRes);
} catch (error) {
console.log(error);
return response.status(401).send();
}
I have no idea what this api is, but I'm going to make an educated guess that Newrequest doesn't return a promise. So awaiting it isn't actually what you want to do.
What you can do, however, is use some simple code to turn it into a promise:
const tokenRes = await new Promise((resolve, reject) => {
Newrequest(options, function(error, res, body) {
if (error) reject(error);
tokenRes = JSON.parse(body);
console.log("token from Zoon API",tokenRes);
resolve(tokenRes);
});
})
You would have to listen to an endpoint at something and you will receive the code over there. This is the code you can send to exchange for an access token.
Please consult this link : https://www.npmjs.com/package/request#promises--asyncawait
You can convert a regular function that takes a callback to return a promise instead with util.promisify()
Example :
Newrequest(options, function(error, res, body) {
if (error) throw new Error(error);
tokenRes = JSON.parse(body);
console.log("token from Zoon API",tokenRes);
});
// to
const util = require('util');
const req = util.promisify(Newrequest)
const data = await req(options)
// ...
It's a sample code. Please adapt with your needs
Useful course : https://masteringjs.io/tutorials/node/promisify
Request library is deprecated
It would be interesting to use another library.
Alternatives :
Got
Axios
Node-fetch
superagent
Almost there, but for some reason my HTTP post request isn't firing and eventually the function timesout. Completely beside myself and posting my code to see if anyone picks up on any noob moves that I'm completely missing. NOTE: the database write completes so I'm assuming that the HTTP Post request isn't firing, is that a safe assumption? Or JS is a different beast?
exports.stripeConnect = functions.https.onRequest((req, res) => {
var code = req.query.code;
const ref = admin.database().ref(`/stripe_advisors/testing`);
var dataString = `client_secret=sk_test_example&code=${code}&grant_type=authorization_code`;
var options = {
url: 'https://connect.stripe.com/oauth/token',
method: 'POST',
body: dataString
};
function callback(error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body);
}
}
request(options, callback);
return ref.update({ code: code });
});
I understand that you want to POST to https://connect.stripe.com/oauth/token by using the request library and, on success, you want to write the code value to the database.
You should use promises, in your Cloud Function, to handle asynchronous tasks. By default request does not return promises, so you need to use an interface wrapper for request, like request-promise
Therefore, the following should normally do the trick:
.....
var rp = require('request-promise');
.....
exports.stripeConnect = functions.https.onRequest((req, res) => {
var code = req.query.code;
const ref = admin.database().ref('/stripe_advisors/testing');
var dataString = `client_secret=sk_test_example&code=${code}&grant_type=authorization_code`;
var options = {
url: 'https://connect.stripe.com/oauth/token',
method: 'POST',
body: dataString
};
rp(options)
.then(parsedBody => {
return ref.update({ code: code });
.then(() => {
res.send('Success');
})
.catch(err => {
console.log(err);
res.status(500).send(err);
});
});
I am attempting to use the request.js library for Node to send a post request with plain text as the body, but I'm finding that the server I'm sending to is receiving an empty body, or perhaps a body consisting of an empty object (logging the body yields {}).
If I send it using Postman, it works properly, so it seems clear that the problem is with my usage of request.js.
The code of the relevant function (with the url changed) is as follows:
function (queryText) {
const options = {
url: "https://myurl.com/",
body: queryText
};
return new Promise ((resolve, reject) => {
request.post(options, (err, response) => {
if (err) reject(err);
else resolve(response);
});
});
}
Anybody know what I'm doing wrong here?
Try adding content-type header like so:
const options = {
url: "https://myurl.com/",
body: queryText,
headers: {
'content-type': 'text/plain'
}
};