jQuery ajaxSetup with ES6 - javascript

How do I replicate the behavior of jQuery's ajaxSetup with vanilla JS (ES6 in this case)?
Here's what I'm trying to achieve. Currently I have in my app.js:
$(document).ready(()=>{
$.ajaxSetup({
data: {'_token': $('meta[name="csrf-token"]').attr('content')}
});
})
So when I perform any ajax request in any other file, _token will be include to the data json object that I'm providing, that way I don't have to specify _token on every call making sure that it's never missed.
How to do this with ES6 only?

Wrap the Fetch api and store your base data and merge that with whatever you send with it.
class MyFetch {
constructor(data) {
this.data = data
}
post(url, data) {
let requestData = {
...this.data,
...data
}
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestData)
})
}
}
let myFetch = new MyFetch({
_token: 'helloworld'
})
myFetch.post('https://httpbin.org/post',{moreData:'more'})
.then((res) => res.json())
.then(json => {
console.log('Data sent:', json.data)
})

Related

Why can't I send a form data from axios?

I am consuming an api that asks me to send a filter series within a formData, when doing the tests from Postman everything works without problem, I tried with other libraries and it also works without problem, but when trying to do it from axios the information does not return with the filters.
This is the code I am using:
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('filtro_grafica', '2,0,0,0');
let config = {
method: 'get',
url: 'https://thisismyurl/filter',
headers: {
'Authorization': 'JWT MYTOKEN',
...data.getHeaders()
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
You can send Form-data using get method, but the most servers, will reject the form data.
However it is not recommended anymore. The reason is, first because it is visible in the URL and browsers can cache them in it’s history backstacks, and second reason is because browsers have some limitations over the maximum number of characters in url.
If you are to send only few fields/input in the forms you can use it but if you have multiple inputs you should avoid it and use POST instead.
At the end it depends on your own usecase. Technically both GET and POST are fine to send data to server.
replace get with post
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('filtro_grafica', '2,0,0,0');
let config = {
method: 'post',
url: 'https://thisismyurl/filter',
headers: {
'Authorization': 'JWT MYTOKEN',
...data.getHeaders()
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});

how to write one GET api call using axios instance with and without params in React JS

I am new to React JS and Axios. I want to understand the best way of creating a GET instance using Axios that works with and without params. I am have developed a sample REST API call from React using axios.create({}) as below and it works fine.
import axios from 'axios';
const instance = axios.create({
baseURL: 'example.com'
});
export default {
getAllData: (url) =>
instance({
'method': 'GET',
'url': url
})
}
My requirement is to create axios GET instance that works with and without params and I could achieve it like below by creating 2 different functions:
export default {
getAllData: (url) =>
instance({
'method': 'GET',
'url': url
}),
getUser: (url, userId) =>
instance({
'method': 'GET',
'url': url,
'params' : userId
})
}
Is there any way to create one GET function that works with and without params using Axios in React JS?
You can do something like this:
getUser: (url, userId) =>
instance({
'method': 'GET',
'url': url,
...(userId && {'params' : userId})
})
If userId exists, it will append the {'params': userId} object to the current one.
You don't have to create 2 different methods. If you don't pass the userId parameter, it will be null and won't be passed to the API call.
You can use this code:
import axios from 'axios';
// Set Global default
axios.defaults.baseURL = 'example.com';
const getData = (url, userId) => axios(url, userId);
export default getData;
You can call with userId:
getData('/user', userId);
Or without:
getData('/user');
This is how you can do it:
export default {
getUser: (url, userId) =>
instance.get(url, {
...(userId && {'params' : userId})
})
}
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})

axios GET request with form data in React JS

I want to implement the following cURL request (which is working) in react js using axios:
curl -k --request GET "BASE_URL_SERVER/sendText" --form "user_id="uidxxxx"" --form "sign_id="
I always get the same error: field sign_id not found, but technically I'm sending it, so I'm kind of desesperate.
var data = new FormData();
data.append('user_id', 'uidxxxx');
data.append('sign_id', '9');
const api = axios.create({
baseURL: BASE_URL_SERVER,
data: data,
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`
},
timeout: 10000,
})
api.get('/sendText')
.then(response => console.log(JSON.stringify(response.data)))
.catch(error => { console.log(error) })
I've also tried adding '...getHeaders()' to the headers section but React says it is not a function; I've read in other posts that it has something to do with the browser
thanks in advance
ps: it is a pretty similar problem to this one, but none of the solutions worked for me
[UPDATE]
I ended up implementing it with POST, which is better for posting Form Data; no headers are needed, the browser automatically adds them:
var data = new FormData();
data.append('user_id', user_id);
data.append('sign_id', sign_id);
const api = axios.create({
baseURL: BASE_URL_SERVER,
timeout: TIMEOUT_SERVER,
})
api.post('/sendText', data)
.then(response => console.log(JSON.stringify(response.data)))
.catch(error => { console.log(error) })
You have a mistake, you try to send data via axios for POST and method is GET...
So that, You need to Change Method to be POST to can Post form data or you need to change it to url param or url path base on your api to be WORK as a GET...
Base on your curl, your case is you need a GET:
// Make a request for a user with a given ID
axios.get('/sendText?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
// Optionally the request above could also be done as
axios.get('/user', {
params: {
sendText: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
Also, you can save all config in instance and share it for all nested of write it again and again..
for example:
// Common Axios Instance Config
const axiosConfig = {
baseURL: process.env.REACT_APP_API_ENDPOINT,
};
// Create Default Axios Instace
const instance = axios.create(axiosConfig);
I think base on your example this will work, but not sure sine I'm not test it..:
var data = new FormData();
data.append('user_id', 'uidxxxx');
data.append('sign_id', '9');
const api = axios.create({
baseURL: 'https://193.146.38.4:56076',
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`
},
timeout: 10000,
})
api.get('/sendText', {
user_id: 111,
sign_id: 2222
)
.then(response => console.log(JSON.stringify(response.data)))
.catch(error => { console.log(error) })
For more details view this url

Posting data into Firebase - with post request - React

I have some posts into Firebase posts.json file that I have manually entered, that look like below, post1, post2...
When I am entering new data - formData object into Firebase with post request like this:
const submitHandler = e => {
e.preventDefault();
const err = validate();
if(err === false) {
setFormData(formData)
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({formData})
};
fetch('https://blog-d8b04-default-rtdb.europe-west1.firebasedatabase.app/posts.json', requestOptions)
.then(response => setLoading(true))
.then(data => setLoading(false));
}
}
I'm getting post like this, with unique keys as names that is generating firebase, and below formData.
But I want they to be the same format like posts I have entered manually into firebase(posts1, post2).
Is there a way to achieve this?
A JSON literal { formData } is actually shorthand for { formData: formData }, which explains the format you end up with.
You're looking for:
body: JSON.stringify(formData)
So without the {} around formData.

Is there a difference in data/promise returned from axios get and post?

I'm working on a React application that makes use of an imported object with a get request to an api and a post request to a related API.
When creating a new instance of my service in the frontend in React, I am able to successfully use the '.then' & '.catch' functions to access the returned data ONLY from the get request.
When using the post request from the same object, when trying to access the response object, I get a (paraphrased) '.then' is not a function on undefined.
Only when I explicitly write out the post request in my form submit function (without consuming a service) and handling the object there am I able to check the response and subsequently set the state.
What is the appropriate/best practice way for using axios in React and why am I not able to access the response object when I create a new instance of a service?? Much appreciated!
Service:
import axios from 'axios';
class ProductServices {
getAllProducts(){
return axios.get('https://somecustomAPIURL')
}
postProduct(somePathConfig){
axios.request({
url: 'https://somecustomAPIURL' + somePathConfig,
method: 'post',
headers: {'some-custom-header': process.env.REACT_APP_API_POST_KEY}
})
}
}
export default ProductServices;
React Code instantiating and consuming the service (note, that getAllProducts works just fine, but trying to consume a response object in postProduct returns an '.then' is undefined)
constructor(){
super();
this.state = {
products: [],
productID: null,
showModal: false
}
this.ProductServices = new ProductServices();
}
getAllProducts = () => {
this.ProductServices.getAllProducts()
.then((response) => {
let items = response.data.data.items;
this.setState({
products: items,
productID: items[0].id
});
return response;
})
.catch((error) => {
console.log('Error!', error);
return error;
})
}
handleFormSubmit = (e) => {
e.preventDefault();
let productID = this.state.productID;
this.ProductServices.postProduct(productID)
.then((response) => {
this.setState({showModal: true}, () => console.log('Success!'));
return response;
})
.catch((err) => {
console.log('Error!', err);
})
}
You missed return before axios.request.
import axios from 'axios';
class ProductServices {
...
postProduct(somePathConfig){
return axios.request({
url: 'https://somecustomAPIURL' + somePathConfig,
method: 'post',
headers: {'some-custom-header': process.env.REACT_APP_API_POST_KEY}
})
}
...
Also, instead of axios.request, you can use axios.post like axios.get
return axios.post(url, body, { headers });
return axios.get(url, { headers });
return axios.put(url, body, { headers });
return axios.delete(url, { headers });
return axios.request(axiosConfigOptions);

Categories

Resources