Axios: How to send Params as Query String - httprequest

This is the base of my code
const params = {
contractId: data.contractId,
notificationEmail: data.notificationEmail,
userNumber: data.userNumber
}
axios.put(update_user_url, params, {
headers: {
Authorization: `Bearer ${authToken}`
}
}).then(blablabla....)
However Axios sends the contractId, email and User fields in body, not as a Query string. How do I make it send a query string?

axios.put(
`${base_url}/user`,
null,
{
params: params,
headers: {
Authorization: token
}
}
);
Check the documentation.

Related

Spotify returning 200 on token endpoint, but response data is encoded

I'm working through this tutorial on creating an app that uses the Spotify API. Everything was going great until I got to the callback portion of authenticating using the authentication code flow.
(I do have my callback URL registered in my Spotify app.)
As far as I can tell, my code matches the callback route that this tutorial and others use. Significantly, the http library is axios. Here's the callback method:
app.get("/callback", (req, res) => {
const code = req.query.code || null;
const usp = new URLSearchParams({
code: code,
redirect_uri: REDIRECT_URI,
grant_type: "authorization_code",
});
axios({
method: "post",
url: "https://accounts.spotify.com/api/token",
data: usp,
headers: {
"content-type": "application/x-www-form-urlencoded",
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
},
})
.then(response => {
console.log(response.status); // logs 200
console.log(response.data); // logs encoded strings
if (response.status === 200) {
res.send(JSON.stringify(response.data))
} else {
res.send(response);
}
})
.catch((error) => {
res.send(error);
});
Though the response code is 200, here's a sample of what is getting returned in response.data: "\u001f�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0003E�˒�0\u0000Ee�uS\u0015��\u000e�(\b\u0012h\u0005tC%\u0010\u0014T\u001e�����0��^޳:���p\u0014Ѻ\u000e��Is�7�:��\u0015l��ᑰ�g�����\u0"
It looks like it's encoded, but I don't know how (I tried base-64 unencoding) or why it isn't just coming back as regular JSON. This isn't just preventing me logging it to the console - I also can't access the fields I expect there to be in the response body, like access_token. Is there some argument I can pass to axios to say 'this should be json?'
Interestingly, if I use the npm 'request' package instead of axios, and pass the 'json: true' argument to it, I'm getting a valid token that I can print out and view as a regular old string. Below is code that works. But I'd really like to understand why my axios method doesn't.
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
const code = req.query.code || null;
const state = req.query.state || null;
const storedState = req.cookies ? req.cookies[stateKey] : null;
res.clearCookie(stateKey);
const authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code',
},
headers: {
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`,
},
json: true,
};
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
const access_token = body.access_token;
const refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { Authorization: 'Bearer ' + access_token },
json: true,
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
// we can also pass the token to the browser to make requests from there
res.redirect('/#' + querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
}));
} else {
res.redirect(`/#${querystring.stringify({ error: 'invalid_token' })}`);
}
});
});
You need to add Accept-Encoding with application/json in axios.post header.
The default of it is gzip
headers: {
"content-type": "application/x-www-form-urlencoded",
'Accept-Encoding': 'application/json'
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
}

Hashnode API with GraphQL API resulting in error

I am trying to call the hasnode API to get blogs as the response, the body is in GraphQL. But I get this error in the Network Tab 'POST body missing. Did you forget use body-parser middleware?'
`
let query = `
{
user(username: "singhmona") {
publication {
posts{
slug
title
brief
coverImage
}
}
}
}
`;
let body = JSON.stringify({
query
});
axios
.post('https://api.hashnode.com/',
body,
{
'content-type': 'application/json',
})
.then(response => {
this.info = response;
console.log(response);}
)
`
I think you should try using fetch. I've had a tough one with axios when using it in node and I was finally able to get the api to work with fetch. Here is a snippet of what worked for me.
const getData = async() => {
const query = `
{
user(username: "misiochaabel") {
publication {
posts(page: 0) {
slug
title
brief
coverImage
}
}
}
}
`;
const response = await fetch('https://api.hashnode.com/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query }),
});
const data = await response.json();
console.log(data);
}

KeystoneJS login via GraphQL mutation

I am trying to login to a Keystone 5 GraphQL API. I have setup the app so that I can login via the Admin Console, but I want to login from a Svelte application.
I keep finding references to the code below (I am new to GraphQL) but don't know how to use it.
mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}
If I post that query "as is" I get an authentication error, so I must be hitting the correct endpoint.
If I change the code to include my username and password
mutation signin("myusername", "mypassword") {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}
I get a bad request error.
Can anyone tell me how I send username/password credentials correctly in order to log in.
The full code I am sending is this
import { onMount } from 'svelte';
let users = [];
onMount(() => {
fetch("http://localhost:4000/admin/api", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}`
})
}).then(res => res.json())
.then(data => {
console.log(data)
})
})
Here is the response I get
{"errors":[{"message":"[passwordAuth:failure] Authentication failed","locations":[{"line":2,"column":3}],"path":["authenticate"],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["Error: [passwordAuth:failure] Authentication failed"," at ListAuthProvider._authenticateMutation (/Users/simon/development/projects/keystone/meetings-api/node_modules/#keystonejs/keystone/lib/providers/listAuth.js:250:13)"]}},"uid":"ckwqtreql0016z9sl2s81af6w","name":"GraphQLError"}],"data":{"authenticate":null},"extensions":{"tracing":{"version":1,"startTime":"2021-12-03T20:13:44.762Z","endTime":"2021-12-03T20:13:44.926Z","duration":164684813,"execution":{"resolvers":[{"path":["authenticate"],"parentType":"Mutation","fieldName":"authenticateUserWithPassword","returnType":"authenticateUserOutput","startOffset":2469132,"duration":159500839}]}}}}
I found the answer eventually.
You have to provide an extra object in your body called variables
variables: {
var1: "value1",
var2: "value2"
}
Those variables will then replace the placehodlers in the query like $var1 or $var2
Here is the full fetch code that works.
fetch("http://localhost:4000/admin/api", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `mutation signin($identity: String, $secret: String) {
authenticate: authenticateUserWithPassword(email: $identity, password: $secret) {
item {
id
}
}
}`,
variables: {
identity: "myusername",
secret: "mypassword"
}
})
}).then(res => res.json())
.then(data => {
console.log(data)
})
It's a shame that KeystoneJS don't provide any full code examples in their documentation. It would have saved me hours of searching.
As you say #PrestonDocks, if your query defines variables, you need to supply the variable values in a separate top level object. For the benefit of others I'll link to the GraphQL docs on this.
The alternative is to not use variables and to in-line your values in the query itself, like this:
mutation signin {
authenticate: authenticateUserWithPassword(
email: "me#example.com",
password: "Reindeer Flotilla"
) {
item {
id
}
}
}
But variables usually end up being neater.

How to set formData for boolean in Axios post request

I'm trying send a post request using axios to my backend but I can't send the boolean "isActive" for some reason. Is there a way to do this?
async submit() {
const isValid = await this.$validator.validateAll()
if (isValid && !this.submitting) {
let formData = new FormData();
formData.set("city", this.formData.city)
formData.set("state", this.formData.state)
formData.set("county", this.formData.county)
formData.set("isActive", true) // <- NOT ACCEPTING THIS VALUE
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.status === 200) {
this.submitting = true
this.cancelModal()
} else {
console.log(res.data.code);
}
})
.catch(function (err) {
console.log(err);
})
}
}
FormData can only contain string values. Setting a Boolean true would result in "true" for the value. The backend would have to convert that string to a Boolean.
Also, your header should not be application/json (intended for JSON payloads). If sending FormData as the payload, the header should be multipart/form-data:
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
If your backend is actually expecting JSON, then you can't send FormData. Switch to a JavaScript object instead (which does accept Booleans):
const payload = {
city: this.formData.city,
state: this.formData.state,
county: this.formData.county,
isActive: true,
}
axios.post("/api/v1/team/createTeam", payload, {
headers: {
'Content-Type': 'application/json'
}
})

How to run GraphQL request in Pre-Request Script section in postman?

I want to run a query before the actual request runs and get a value from the pre-request response and set it in a collection variable.
I have a problem running the following as I used to do it while testing REST APIs.
This is what I tried to do
const getUserBeforeUpdate = {
url: pm.environment.get("base-url"),
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${pm.environment.get("token")}`},
body: JSON.stringify({query: '{ user { profile {id} } }'})
};
pm.sendRequest(getUserBeforeUpdate, function(err, response) {
pm.expect(response.code).to.eql(200);
// set collection variable from the response
});
but I get a console error stating
There was an error in evaluating the Pre-request Script: Error: Unexpected token u in JSON at position 0
What's the right way to chain requests in graphql?
Collection variable are accessible via collectionVariables. This should work for you:
const getUserBeforeUpdate = {
url: pm.collectionVariables.get("base-url"),
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${pm.collectionVariables.get("token")}`},
body: JSON.stringify({query: '{ user { profile {id} } }'})
};
pm.sendRequest(getUserBeforeUpdate, function(err, response) {
pm.expect(response.code).to.eql(200);
// set collection variable from the response
});
I was able to fix this by changing the url value to the actual url directly as a string. I'm not sure why getting the variable from environment didn't work yet.
I don't have the ability to run you request but would this work?
const getUserBeforeUpdate = {
url: `${pm.environment.get("base-url")}`,
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${pm.environment.get("token")}`},
body: JSON.stringify({
query: 'query { user { profile { id } } }'
})
};
pm.sendRequest(getUserBeforeUpdate, function(err, response) {
pm.expect(response.code).to.eql(200);
// set collection variable from the response
});