How to get JSON in Laravel from vue.js axios POST? - javascript

I have some problem with receiving JSON data from vuex with axios in my Laravel Backend.
I have vuex store like this, and I want to send it to backend on click.
order: {
delivery_id: null,
user_id: null,
is_active: true,
bill: null,
name: null,
surname: null,
father_name: null,
phone: null,
payment_type: 'cash',
delay: null,
cashback_paid: null,
card: null,
payment_screenshot: null,
cart: null,
}
In vue component I have this method:
sendOrder() {
let order = this.$store.state.order.order;
console.log(order)
axios
.post('/api/products', order, {
header: {
'Content-Type': 'application/json'
}
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
})
}
And this is my pretty simple Laravel Controller:
$test = json_decode($request->getContent(), true);
$test = $test['payment_type'];
return response($test);
But when I'm doing this POST request, I'm receiving empty data in response.
Also, I've tried to check my API with Postman, and it's working fine. I just send request, then go to F12 > Network > find my request and copy Request Payload source data. Then I've pasted it into Postman body (raw, json) and make request with this data to same url (http://localhost:8000/api/orders), and its return 'cash' as expected. So I decided, that it's vue.js or axios problem, but I have no idea how to fix that. Thank you!
UPDATED
I already have tried to remove Content-Type from axios, JSON.stringify order and had the same result - empty data on response.

I think, before you use order in axios you should stringify the JSON data:
let order = JSON.stringify(this.$store.state.order.order);
Second part of the answer after some comments:
Are you sure about the routes file? I would call the controller from the web.php file (same folder) with a declared function (for example mytest), like this:
Route::post('/api/products', 'ProductController#mytest');
and put your controller logic in that function:
public function mytest()
{
$test = json_decode($request->getContent(), true);
$test = $test['payment_type'];
return response($test);
}
If that doesn't work (also in combination with JSON.stringify), my only idea is a typo in your "pretty simple Laravel Controller" ;)...

Related

Axios get call in Vue3 not working, although curl and javascript work as expected

I'm trying to make an API call from my Vue3 app. The prepared API has an endpoint like http://localhost:8888/api/dtconfigsearch, where one needs to pass a json payload like { "Modelname": "MyFancyModel"} to get the full dataset with the given modelname. Pure get functions without a payload / a body do work from my Vue3 project to the golang backend, but I'm having problems with passing a payload to the backend.
Test with curl -> ok
$ curl -XGET localhost:8888/api/dtconfigsearch -d '{"Modelname" : "MyFancyModel" }'
{"ID":4,"Modelname":"MyFancyModel","ModelId":"96ee6e80-8d4a-b59a-3524-ced3187ce7144000","OutputTopic":"json/fancyoutput"}
$
This is the expected output.
Test with javascript ok
Source file index.js:
const axios = require('axios');
function makeGetRequest() {
axios.get(
'http://localhost:8888/api/dtconfigsearch',
{
data: { Modelname : "MyFancyModel" },
headers: {
'Content-type' : 'application/json'
}
}
)
.then(resp => {
console.log(resp.data)
})
.catch(err => {
console.log(err)
})
}
makeGetRequest()
Output
$ node index.js
{
ID: 4,
Modelname: 'MyFancyModel',
ModelId: '96ee6e80-8d4a-b59a-3524-ced3187ce7144000',
OutputTopic: 'json/fancyoutput'
}
$
Here, I also get the desired output.
Test within Vue fails :-(
Source in the Vue one file component:
onSelection(event) {
let searchPattern = { Modelname : event.target.value }
console.log(event.target.value)
console.log("searchPattern = " + searchPattern)
axios.get("http://localhost:8888/api/dtconfigsearch",
{
data : { Modelname : "Windshield"},
headers: {
'Content-type' : 'application/json',
'Access-Control-Allow-Origin': '*'
}
})
.then(response => {
console.log(response.data)
})
.catch(err => {
console.log(err)
alert("Model with name " + event.target.value + " not found in database")
})
},
Output in browser:
In the image you can see in the terminal log on the right side that the backend is not receiving the body of the API call. However, in the browser information of the call there is content in the config.data part of the object tree, which is the payload / the body. The only thing that bothers me that it is not a json object, but stringified json, although it was entered as json object. According to the documentation, the parameter name (data) in the call should be correct to hold the body content of the api call.
I've tried different header information, looked if it could be a CORS issue, what it isn't to my opinion, exchanged key data with body, used axios instead of axios.get and adapted parameter, all without success. The version of the axios library is 0.27, identical for Vue and vanilla javascript. After checking successfully in javascript, I was sure that it would work the same way in Vue, but it didn't.
Now I'm lost and have no further ideas how to make it work. Maybe someone of you had similar issues and could give me a hint? I'd be very grateful for some tipps!!

Get token from URL and send to post api with Axios Vuejs

Hi i need to take token from URL http://192.168.178.25:8080/register?token=eyJhbGciOiJIUzI...
and send a Post request on API for confermation account
I have tried this but on backend i've receive SyntaxError!
Someone can help me?
<script>
import axios from 'axios'
export default {
name: 'Register',
data() {
return {
confirmation : false,
somethingWrong: false
}
},
created: function() {
axios.post('/api/users/validateRegister', null,{
params: {
registerToken: this.$route.query.token,
state: this.$route.query.state
}
})
.then((res) => {
console.log(res)
this.confirmation = true
})
.catch((err) => {
console.log(err)
this.somethingWrong = true
})
}
}
</script>
Your server is expecting JSON but you are sending something else.
Try running this in your browser console (devtools): JSON.parse('asdasd').
How you are sending it right now:
axios.post('/api/users/validateRegister', null,{
params: {
registerToken: this.$route.query.token,
state: this.$route.query.state
}
})
Will send a request that looks like:
/api/users/validateRegister?registerToken=<token>&state=<state>
To do a POST request with body according to docs, you do:
axios.post(url[, data[, config]])
Which in your case means, assuming you need registerToken and state as part of body and not query parameters:
axios.post('/api/users/validateRegister',{
registerToken: this.$route.query.token,
state: this.$route.query.state
})
Notice how there's no null in the 2nd param and no params: {}
You can also according to docs do the following syntax:
axios({
method: 'post'
url: '/api/users/validateRegister',
data: {
registerToken: this.$route.query.token,
state: this.$route.query.state
}
})
It looks like your server is throwing an error when trying to parse the body.
From your axios request, you're passing parameters instead of a body - you can see this by looking at the URL in the POST error on the right-hand side of your screenshot.
Instead, send the payload in the body like this;
axios.post('/api/users/validateRegister',
{
registerToken: this.$route.query.token,
state: this.$route.query.state
})
As you haven't provided any of the server-side code there may be something else going on we can't see.

How to send JSON data correctly using Axios to a rails server, to match the required rails params hash correctly?

I am making a GET request to a rails server, and the parameter should look like:
{"where"=>{"producer_id"=>["7"]}
I am making the request from the frontend application which is in Vue, and using Axios for making the request. I am making the request like this:
const data = await this.axios.get('http://localhost:3000/data.json', {
headers: {
'X-User-Token': this.$store.getters.authToken,
'X-User-Username': this.$store.getters.user.username
},
params: {
where: {
producer_id: data.producers
}
}
})
However, in the rails server output it shows that the params were sent like this:
{"where"=>"{\"producer_id\":[\"7\"]}"}
And I don't get the correct data back because of it.
How can I solve this? Why is the second level in params (the where object) being sent as a string?
Turns out that in this case the params have to be serialized https://github.com/axios/axios/issues/738
I used the paramsSerializer function as well to get over this
const data = await this.axios.get('http://localhost:3000/data.json', {
headers: {
'X-User-Token': this.$store.getters.authToken,
'X-User-Username': this.$store.getters.user.username
},
params: {
where: {
producer_id: data.producers
}
},
paramsSerializer: function (params) {
return jQuery.param(params)
}
})
EDIT:
I am now using qs instead of jQuery:
axios.defaults.paramsSerializer = (params) => {
return qs.stringify(params, {arrayFormat: 'brackets'})
}

How to POST an XML with Angular http?

I'm having trouble using JavaScript to send xml. I've tried to emulate what many others have done, but I'm not getting success. I'm getting a XML Syntax Error: Please check the XML request to see if it can be parsed. with the code 80040B19.
Here's my code. I'm trying to use the USPS Address Validation API. On page 4 of this doc, there's more info.
const apiUrl = 'http://production.shippingapis.com/ShippingAPI.dll?API=Verify';
validate(address: Object): any {
const payload = this.xmlBuilder.buildObject({
AddressValidateRequest: {
$: { USERID: 'XXXXXXXXX' }, // api key hidden
Address: {
$: { ID: '0'},
FirmName: null,
Address1: address['address2'],
Address2: address['address1'], // NOT A TYPO, they swap it
City: address['city'],
State: 'NY',
Zip5: address['postal_code'],
Zip4: null
}
}
});
console.log(payload); // SEE BELOW
const headers = new Headers({ 'Content-Type': 'text/xml' });
const options = new RequestOptions({ headers: headers });
return this.http.post(this.apiUrl, { 'XML': payload }, options)
.map((res) => {
this.parseXMLStringToObject(res.text(), (err, result) => {
console.log(result);
});
});
}
Here's what my console.log on the payload reads. I've verified this to the letter, from the order of the xml tags, to what is required tag but optional value. I'm positive the payload is correct.
<AddressValidateRequest USERID="XXXXXXXXX">
<Address ID="0">
<FirmName/>
<Address1/>
<Address2>620 Eighth Avenue</Address2>
<City>New York</City>
<State>NY</State>
<Zip5>10018</Zip5>
<Zip4/>
</Address>
</AddressValidateRequest>
One thing that I can think of is I'm somehow not using the http correctly, and I'm sending a blank xml somehow.
On their docs, they have this listed:
https://servername/ShippingAPI.dll?API=Verify&XML=……..
I noticed I'm not doing a XML in the url, but I'm assuming that when I input the Content-Type: text/xml, that it get converted. I've also tried application/xml which give the same error.
From the documentation on USPS website it seems that the call isn't a POST with the XML as payload but a GET with XML (I suppose urlencoded) in the URL XML parameter.

Angular 2 *ngFor and form submit ceased working when moved to observables

I had an app initiating course components like this:
<li *ngFor="let course of courses">
<app-course [appCourse]="course"
(remove)="removeItem($event)"
></app-course>
</li>
from an array pulled from local storage, which was populated from a course form, sending an object like this:
{
"_id": "587f52ad266c32fbfb10f21a",
"end": "31/1/2017",
"start": "1/1/2017",
"desc": "see title",
"name": "Intro To Express",
"id": 1,
"__v": 0,
"updated_at": "2017-01-18T11:34:05.416Z"
}
Then I added a back end with observables. Now, the form submits an object, I can see if I console log it that it's in the right shape.
Then it goes to an intermediary service, which pushes it to the service which manages the backend:
addItem(course) {
this.storage.post(course).subscribe((data: any) =>
{console.log(JSON.stringify(data)); return (data); }, error =>
{console.log(error)});; }
I can still see the object as I'm pushing it to to the service from my main component with console.log():
{"name":"test","id":"1234","desc":"test","start":"2017-01-30‌​","end":"2017-02-03"‌​}
But when it actually gets to the database, none of the fields from the form are present:
{
"_id": "588f251bff96fa0004e0c2cd",
"__v": 0,
"updated_at": "2017-01-30T11:35:55.567Z"
}"
Also, the array still comes back-I can see it with console.log(), but my ngFor no longer initiates components.
There are no errors.
What should I check?
Got it!
The first issue was properly subscribing to the observable.
ngOnInit() {
this.appListService.getAppList()
.subscribe(res => this.courses = res);
}
The App List Service is just acting as a manager in this case, so it is just returning an observable:
constructor(private storage:CoursesService) { }
getAppList() {
return this.storage.get();
}
The Courses Service makes the GET request to the backend:
get(): Observable<Course[]> {
return this.http.get(this.BaseUrl)
.map((res:Response) => res.json())
.catch(this.handleError);
}
When the resulting observable gets passed up to the main component, the ngFor works fine.
Now, for the POST. First of all, I had to JSON.stringify() the body, like this:
post(course: Course): Observable<Course[]> {
let courseString = JSON.stringify(course);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.BaseUrl, courseString, options)
.map((res:Response) => res.json())
.catch(this.handleError);
}
Then, I went on the back end and adjusted the POST so that instead of replying with a success message, it replied with the results of a general GET request.
Now, everything works fine (except for all the work that remains to do, of course.)

Categories

Resources