I have a route in Rails API '/api/pay'. My client side post request successfully hits the controller action, however nothing I send in the body: JSON.stringify('...') gets through to the back-end. Other post requests I have made work just fine with the same format.
export const payForItem = (payData) => {
return dispatch => {
dispatch(payForItemStart());
// ?userID=${data.userID}&adID=${data.adID}&price=${data.price}
const data = {userID: payData.userID, adID: payData.adID, price: payData.price}
fetch(`/api/pay`, {
method: 'POST',
header: {
'content-type': 'application/json'
},
body: JSON.stringify(data)
})
Here is what payData looks like.
Rails Api back-end params
Probably you've got typo in headers section. Should be plural headerS with s:
headers: {
"Content-Type": "application/json"
}
Related
I want to post multiple logs to DataDog from a JS function, using a single HTTP request. Looking at the v2 docs for DataDog's 'send logs' POST endpoint, it sounds like this is possible:
For a single log request, the API ... For a multi-logs request, the API ...
But it's not clear to me from the docs how to actually send a 'multi-logs' request. I've tried the following:
const dataDogEndpoint = 'https://http-intake.logs.datadoghq.com/api/v2/logs';
const body = {
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: ['My first production log.', 'My second production log.'],
service: 'my-service'
};
const response = await fetch(dataDogEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': apiKey
},
body: JSON.stringify(body)
});
Perhaps unsurprisingly, this appears in DataDog as a single log with the following content:
[My first production log., My second production log.]
How can I achieve this?
Got it - this can be achieved by adding multiple log objects to the body like so:
const dataDogEndpoint = 'https://http-intake.logs.datadoghq.com/api/v2/logs';
const body = [{
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: 'My first production log.',
service: 'my-service'
},{
ddtags: 'env:production,status:info',
hostname: 'my-host',
message: 'My second production log.',
service: 'my-service'
}];
const response = await fetch(dataDogEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': apiKey
},
body: JSON.stringify(body)
});
(You'll probably want a loop instead of instantiating each log object separately.)
I'm trying to setup a website using Wordpress as Headless CMS, using the built-in REST API. Using NuxtJS to fetch the data. Now I want to restrict API access so I enabled/created Wordpress Application Password Authentication.
However, I can not seem to find detailed information on how the URL should be assembled with authentication parameters to fetch data from API endpoint.
Credentials have to be added to the URL that's being fetched?
async asyncData ({ $config: { apiUrl, apiUser, apiPassword } }) {
try {
const products = await (await fetch(`${apiUrl}/producten`)).json()
return {
products
}
}
catch (error) {
console.log(error)
}
},
apiUrl, apiUser, apiPassword are currently in nuxtjs.config.js, under publicRuntimeConfig. But 1) they should come in privateRuntimeConfig?
And 2) getting following as return (which is the correct response from the WP Rest API, because I need to pass auth-credentials somewhere, somehow...)
{ "code": "rest_not_logged_in", "message": "You are not currently logged in.", "data": { "status": 401 } }
Solved by adding options to fetch;
const fetchHeaderOptions = {
cache: 'no-cache',
method: 'GET',
credentials: 'omit', //To instead ensure browsers don't include credentials in the request
mode: 'no-cors',
headers: {
'Authorization': 'Basic ' + encode(`${apiUser}` + ":" + `${apiPassword}`),
'Content-Type': 'application/json; charset=UTF-8; application/x-www-form-urlencoded',
},
}
const products = await (await fetch(`${apiUrl}/products`, fetchHeaderOptions)).json()
The following code authorizes my strava account in my web app:
function Authorize() {
document.location.href = "https://www.strava.com/oauth/authorize?client_id=xxxxx&redirect_uri=https://localhost:44389/home/strava&response_type=code&scope=activity:read_all"
}
const codeExchangeLink = `https://www.strava.com/api/v3/oauth/token`
function codeExchange() {
fetch(codeExchangeLink, {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
client_id: '#ViewBag.cId',
client_secret: '#ViewBag.cSec',
code: '#ViewBag.code',
//need to do this to get a new refresh token that 'reads all' and issues a new Access Token - refer to comments below
grant_type: 'authorization_code'
})
})
.then(res => res.json())
.then(res => getActivities(res))
}
However, when I publish to azure and change the document.location.href code and redirect address (as below) to match my published app it fails with a 'bad request' error.
document.location.href = "https://www.strava.com/oauth/authorize?client_id=xxxxx&redirect_uri=https://xxxx.azurewebsites.net/home/strava&response_type=code&scope=activity:read_all"
Error is included below:
{"message":"Bad Request","errors":[{"resource":"Application","field":"redirect_uri","code":"invalid"}]}
Any help greatly appreciated
This was totally my error (embarrassingly). The issue was in my Strava Api App Settings, my call back uri was set to the default 'developers.strava.com'. All I had to do was change it to match my Published Web App uri 'xxxx.azurewebsites.net/home/strava' and it now works.
I'm running TestCafe for UI automation, using ClientFunctions to trigger API requests (so that I can pass along session cookies).
Currently I have a ClientFunction with fetch which works fine... except we're now testing IE 11 and Fetch is unsupported.
Fetch code:
const fetchRequestClientFunction = ClientFunction((details, endpoint, auth, method) => {
return window
.fetch(endpoint, {
method,
credentials: 'include',
headers: new Headers({
accept: 'application/json',
'Content-Type': 'application/json',
}),
body: JSON.stringify(details),
})
.then(httpResponse => {
if (httpResponse.ok) {
return httpResponse.json();
}
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
However when I try to switch it to axios... not so much:
import axios from 'axios';
const axiosRequest = ClientFunction((details, endpoint, auth, method) => {
return axios({
method,
auth,
url: endpoint,
data: details,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
timeout: 3000,
})
.then(httpResponse => {
if (httpResponse.status < 300) return httpResponse;
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
Tried using window.axios, and also passing axios as a dependency. I've also tried making the axios request without the ClientFunction... and despite getting response of 200, the website wasn't updated as expected.
Each time I either get _axios2 is not defined or window.axios is not a function. I would greatly appreciate some guidance here.
TestCafe ClientFunctions allow only serializable objects as dependencies. You need to have axios on the client side to send such a request.
I'm uploading images with formdata and axios. I'm using symfony for my back end and I need to access my image file and other parameter both. This is my axios code.
axios.post(testUp, { data: formData, ad: 12 }, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
});
And here is my symfony code.
/**
* #Route("/test_up", name="test_up", methods={"GET","POST"})
*/
public function testUp(Request $request, CarRepository $carRepository) {
dd($request->files->all());
}
Unfortunately I'm getting null as output. I'm getting the formdata from image uploaded and it's a formdata object. It works if I do this but need both parameters.
axios.post(testUp, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
alert('*');
console.log(response);
});
but I need to send other parameter too.
You cant mix FormData with JSON. It is related question
Send FormData object AND an additional parameter via ajax
If you have only one parameter - ad = 12 I recommend to use code:
axios.post(testUp + "?" + (new URLSearchParams({ad: 12})).toString()
, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
alert('*');
console.log(response);
});
On Symfony side you should use a form so you can receive many type of data. See documentation here: https://symfony.com/doc/current/forms.html
On vuejs/axios side, you just cant send json content AND form data content at the same time (as it is 2 different type of data). But you can add some content to your form data (just like you can have a file with other fields in your Symfony form).