I have this code:
import axios from 'axios'
const storeDevices = values => {
axios.create({
baseURL: 'http://localhost:8000/something/store',
method: 'POST',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
data: values
});
}
export default storeDevices;
The following code is correct because it returns an object with all data from my form
const storeDevices = values => {
console.log(values);
}
export default storeDevices;
Interestingly if I try to use .then I have an error:
axios__WEBPACK_IMPORTED_MODULE_0___default.a.create(...).then is not a
function
Code with .then
axios.create({
baseURL: 'http://localhost:8000/something/store',
method: 'POST',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
data: values
}).then(res => {
console.log(res);
console.log(res.data);
});
It's because you've never told axios to send a POST request. axios.create creates a new instance of axios with a custom config. This instance have different methods (like .get(), .post(), etc.), none of which is then(), so that's why you received the error .then is not a function. You set the default method to POST but you've never sent a request.
I think you wanted to create this new instance because you didn't want to add the base URL and headers every single time. If you want to create a base instance, you can assign the returned value to a new variable:
const API = axios.create({
baseURL: 'http://localhost:8000/api/',
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
});
And use this instance to post your request:
API.post('store', data)
.then(res => {
console.log(res);
console.log(res.data);
});
can you try to post using this sintax?
axios.post('http://localhost:8000/something/store', values, {headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},}
}).then(res => {
console.log(res);
console.log(res.data);
});
Related
I am trying to hit API with axios but response.data variable is empty. While using axios.create but when i directly hit API with axios.post. It works fine. I want to get the response through axios.create. Here is my axios create code
const client = axios.create({
baseURL: BASE_URL,
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
});
And my method for post request is:
export const postRequest = (url, payload = {}) => client.post(url, payload);
And when i request i call this method:
const res = await postRequest('/login', body)
axios.create returns a client that has the property .request, not .post
Example from https://masteringjs.io/tutorials/axios/create-post
const client = axios.create({
url: '/post',
baseURL: 'https://httpbin.org',
method: 'POST',
timeout: 1000
});
let res = await client .request({
data: {
name: 'Masteringjs.io',
email: 'Masteringjs#io'
}
});
res.data.json // ↓
// { email: 'Masteringjs#io', name: 'Masteringjs.io' }
So your code would look like this:
const client = axios.create({
baseURL: BASE_URL,
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
method: "POST"
});
export const postRequest = (url, payload = {}) => client.request({ url, data: payload });
const res = await postRequest('/login', body)
You need to do this. I am using this test API https://jsonplaceholder.typicode.com/ you can cross-check my snippet response with the mentioned URL.
const client = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com',
});
client({
'method': 'GET',
'url': '/todos/1'
}).then((res) => console.log(res.data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
I am working on user authentication using web tokens in react. I am using fetch() to make a POST request to my backend using CORS. Trying to use setToken() hook inside the .then() gives an error. I tried storing the token to another variable, and using setToken() outside the promise, but to no avail. Here's the code:
const [ token, setToken ] = useState('')
// Configuration for POST fetch method
const url = 'http://localhost:8080/users/login'
const requestOptions = {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(userData)
}
let tempToken = ''
fetch(url, requestOptions)
.then(res => res.json())
.then(data => {
tempToken = data.token
// console.log(tempToken) // DEBUG
})
.catch(e => console.log(e))
setToken(tempToken)
// console.log(token) // This logs default value of token, which is ''
This is all inside a function. What is going wrong here? Also is there another way to do this, much appreciated. Thanks.
What is my problem: Cannot extract token from promise.
P.S: Also, on a completely different note, I tried using async await but it gave a response (shown below), where I couldn't even find the body of the json. Hence using .then()
Response {type: "cors", url: "http://localhost:8080/users/login", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:8080/users/login"
__proto__: Response
Fetch returns a promise, you need wait to get the token and then use setToken. Moreover you're calling fetch directly and updating the state even before rendering, that might leads to warnings/side effects. You can use useEffect hook to call api and update the state
useEffect(() => {
const url = 'http://localhost:8080/users/login'
const requestOptions = {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(userData)
}
fetch(url, requestOptions)
.then(res => res.json())
.then(data => {
setToken(data.token)
})
.catch(e => console.log(e))
}, [])
i want to pass formdata and data in body parameter in axios post request, i tried some way but its not working.
//code
const form = new FormData();
form.append("file", this.state.selectedFile);
const data={
token:localStorage.getItem('token'),
}
axios.post('http://localhost:3000/api/upload',form, {
onUploadProgress: ProgressEvent => {
this.setState({
loaded: (ProgressEvent.loaded / ProgressEvent.total*100),
})
},
})
.then(response=>{
console.log(response)
}).then(res => {
toast.success('upload success')
})
.catch(err => {
toast.error('upload fail')
})
You need to provide valid headers for respective content type
axios({
method: 'post',
url: 'http://localhost:3000/api/upload',
data: form,
headers: {'Content-Type': 'multipart/form-data' }
})
You are trying to pass a file in FormData which is not possible and you need to use FormUrlEncoded. To do so you also need to install a npm package named query-string and then your data property would look something like this:
import qs from 'query-string';
...
axios.post(..., data:qs.stringify({
file: this.state.selectedFile
})
Edit: Could this be a CORS issue, I'm on localhost...
In Javascript I can set the request headers and get and return a response like so:
$(function() {
var params = {
// Request parameters
};
$.ajax({
url: "https://demo-api.com/",
beforeSend: function(xhrObj){
// Request headers
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","{API KEY}");
},
type: "GET",
// Request body
data: "{body}",
})
.done(function(data) {
alert("success");
})
.fail(function() {
alert("error");
});
});
Question:
I want to learn VueJs and would like replicate this with VueJs + Axios, however I am confused as to how to set the request headers as I have in the above JS.
Here is my failed attempt:
new Vue({
el: '#app',
data () {
return {
info: null,
loading: true,
errored: false,
response: false
}
},
mounted () {
axios({
method: 'get',
url: 'https://demo-api.com/',
headers: {
'Ocp-Apim-Subscription-Key': 'API KEY',
}
})
.then(response => {
console.log(response)
this.response = true
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false)
}
})
How can I specifically set the request headers as I have in the above JS. I am wanting to learn how to implement the below in Vue/Axios.
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","{API KEY}");
Thanks.
Difference between the created and mounted events in Vue.js
Read an answer and try to use created() lifecycle hooks instead of mounted()
Furthermore, you can create separate instance of axios for request with this header and then use it inn you code:
axios-demo-api.js
import axios from 'axios'
const instance = axios.create({
baseURL: 'https://demo-api.com',
headers: {'Ocp-Apim-Subscription-Key': 'API KEY'} //don't forget to change API key to your exact key
})
export default instance
Usage:
import axiosInstance from 'axios-demo-api';
export default {
created() {
axiosInstance.get('/{demoId}?' + $.param(params))
.then(response => {
console.log(response)
this.response = true
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false)
}
}
Your problem is not the header. You are setting it properly. It has to do with the URL. You are constructing your URL like this:
url: 'https://demo-api.com/{demoId}?" + $.param(params)',
Your URL string is wrong. It has an extra quote at the end. That's why you got 404 error. This is what you need to do:
url: "https://demo-api.com/{demoId}?" + $.param(params),
Also, if you are using Vue and not jQuery, then you should not use $.param function. Instead, use a proper query string module like qs. So your actual URL would be like:
url: `https://demo-api.com/${demoId}?${qs.stringify(params)}`,
Here we are using ES2015 string interpolation.
I'm using React and Axios to post formData to an internal .NET API.
The API is expecting data like this:
[HttpPost("upload")]
public virtual async Task<IActionResult> PostMulti(Int64 parentId, ICollection<IFormFile> fileData)
{
foreach (var file in fileData) {
await SaveFile(file, parent);
}
return Created("", Map(Repository.Get(parentId)));
}
When I step through the debugger, the count for "fileData" is always 0.
Here is how I'm sending it using Axios:
const formData = new FormData();
formData.append('image', this.state.file);
console.log("this.state.file = ", this.state.file);
console.log("formData = ", formData);
axios({
url: `/api/gameMethods/playerStates/${this.props.playerId}/files/upload`,
method: 'POST',
data: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
}
})
.then((response) => {
//handle success
console.log('response -- then: ', response);
this.setState({
file: this.state.file
});
})
.catch((response) => {
//handle error
console.log('response -- catch: ', response);
});
I use console.log for debugging. It shows me the file object when I write it out(name, size, etc).
It also fires in the ".then" handler of the method and shows this:
"response -- then: data: Array(0), status: 201, statusText: "Created"
"
So, I have no idea why it's not sending anything to the API and I don't really know what's happening or how to fix this problem.
Any help would be greatly appreciated.
Thanks!
You should post array of the formData
const filesToSubmit = []
filesToSubmit.push((new FormData()).append('image', this.state.file))
and while posting the data the property name should be formData
axios({
url: `/api/gameMethods/playerStates/${this.props.playerId}/files/upload`,
method: 'POST',
data: {formData : filesToSubmit},
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
}
})
If there is an issue with constructing an array you need to add IFormFile properties to the array
So I had exactly the same issue, whereby no matter which way I twisted the FormData object and regardless of the headers I sent, I couldn't get .NET to accept the submission.
From the Node.js side, it was difficult to actually inspect the HTTP call issued by Axios - meaning I couldn't see what I was actually POSTing.
So I moved the POST to the UI for some debugging, and found that the FormData payload was not being passed as I was expecting, so it was proper that .NET was rejecting.
I ended up using the configuration below, and the POSTs began going through. Again, in my case, I thought I needed FormData, but the below was simple enough:
axios({
url: myUrl,
method: 'POST',
data: `email=${myEmail}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
Update: Not sure how encoded data will work, but since it'll be passed as a string, it's worth a shot!
const myUploadedImage = "data:image/png;name=colors.png;base64,iVBORw0KGgoAAAANSUhEUgAAA5gAAAEECAIAAADCkQz7AAAGGUlEQVR4nO3YIY/IcRzHcWd4AjZJkZQr2I1dIJlyRU5ErkJggg=="