laravel vue.js axios json object extra string appended - laravel

I started working with laravel and vuejs. I have encountered a problem fter doing a post to the server and returning a message. The result contains an extra string to the json object returned by the server. My server side code
try{
$this->_gFormsService->saveGlobalForm($request);
}catch (\Exception $e){
echo $e;
}
return ['message'=>'Form created'];
Client side code
submit(requestType, url) {
return new Promise((resolve, reject) => {
delete this.errors;
axios[requestType](url, this)
.then(response => {
debugger
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
debugger
this.onFail(error.response.data);
reject(error.response.data);
});
});
}
The resulted json response is
{data: "section{"message":"Form created"}"
As you can see it appends "section" to the jsonobject and i have no idea why.
Thx

Try returning a bona fide JSON response from Laravel:
return response()->json(['message'=>'Form created']);
Then on your front-end you'll be able to get your message property from response.data .

Related

How do I blend a promise with an observable?

I'm having trouble promises and observables. I have a handful of http requests which are defined in a package using promises. In the rest of my code I am using observables for various things, including other http calls. In one particular section I am checking to see if the user's bearer token is expired and if so then I get a new token and then proceed with the rest of the call.
if (!token || token.exp < Math.round((new Date()).getTime() / 1000)) {
from(this._store.refreshBearerToken())
.pipe(flatMap(resp => {
let newToken = resp.data;
newToken.exp = (new Date()).getTime() / 1000 + newToken.expires_in;
localStorage.setItem('token', JSON.stringify(newToken))
options = options || {};
options.headers = new HttpHeaders({
"Authorization": `${newToken.token_type} ${newToken.access_token}`,
"Content-Type": "application/json"
});
return this._http$.request<T>(method, url, options as Object).pipe(share());
}));
}
Bearer Token method:
async refreshBearerToken() {
const response = await this._q2.sources.requestExtensionData({
route: "refreshBearerToken"
});
console.log(response);
return response;
}
Since this._store.refreshBearerToken returns a promise I wrapped the call in a from to convert it to an observable. This compiles but when it runs I get "Cannot read property 'pipe' of undefined".
How can I convert this promise to an observable so that I can refresh the token and then continue with the rest of the call?
Edit:
I am importing from via import { Observable, from } from "rxjs";.
So, I thought the error was coming from the line .pipe(flatMap(resp =>... but I was wrong. The error is coming from the method which is calling this.
GetInitialLinkList(): Observable<Institution[]>
{
let base = { 'MemberId': localStorage.getItem('memberId') };
let ins = localStorage.getItem("initialInstitutionList");
if (ins)
{
return of(JSON.parse(ins));
}
return this._settingsService.get().pipe(
flatMap(settings =>
{
this._settings = settings;
return this._api.request<Institution[]>("Post", `${this._settings.mea}/GetInitialLinkList`, { body: base })
.pipe(
retry(1),
catchError(this.handleError)
)
.pipe(flatMap(instList =>
{
localStorage.setItem("initialInstitutionList", JSON.stringify(instList));
return of(instList);
}))
}));
}
and that is being subscribed to inside my component:
private GetLinkList()
{
this.showWaiting.emit(true);
this._data.GetInitialLinkList().subscribe((result) =>
{
this.initialList = result;
this.showWaiting.emit(false);
});
}
From what Brandon said (I forgot to return /facepalm...) I added the return so I have return from(this._store.refreshBearerToken()) which changed my error to
ERROR Error Code: undefined
Message: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
defaultErrorLogger # core.js:6014
Can you show the actual error and the line in the code that the error occurs on? Also show where and how you import from.
I notice your code snippet does not return the observable it builds up via from(...).pipe(...) nor does it subscribe to it. It might help to show how your code actually uses this observable.

Getting data from response headers in axios

I'm making a post request using Axios and this call returns data in the response headers and body. In the headers, it's returning an x-auth-token and I want to get the value of this token but it returns:
undefined is not an object
Here is how I'm doing it:
axios.post('app.com/api/login', data)
.then(response => {
console.log(response.headers.get("x-auth-token"));
})
.catch(error => {
console.log(error)
});
You need to parse your response first.
axios
.post('app.com/api/login', data)
.then(response => response.json())
.then(response => {
console.log(response.headers.get("x-auth-token"));
})
.catch(error => {
console.log(error)
});
After that, In second then you can log the whole response and find where your x-auth-token resides.
In the Github comment, it's clearly mentioned how to retrieve the headers
see
fetchFromServer = async(data) => {
const response = await axios.post(url, data, headers)
console.log(response.headers)
}
If you could see all the headers in your log you can try either of these to get the data from the response. To check the keys available in your response you can try
console.log(Object.keys(response.headers))
console.log(response.headers.your_required_key (For example response.headers.token)
console.log(response.headers["your_required_key"] if the above fails. (console.log(response.headers["content-type"])

TypeError: Cannot read property 'status' of undefined when receiving errors from Laravel validation

I'm trying to validate a form via AJAX using Axios with vue.
axios.post('api/registro', this.sede)
.then(response => {
this.$emit('cerrar')
})
.catch(err => {
console.log(err)
})
The error comes from the catch part, as it's coming from a Laravel validator. The response from the server is 422 and it contains a JSON with a message and the errors the server is sending.
Everything works fine if I dont try to log the error.
The problem was coming from me using interceptors in axios, I wasn't returning the errors in the interceptors properly, so nothing was coming into the catch function.
This is what I had:
axios.interceptors.response.use(null, function (error) {
// some logic
});
And this is how it should've been:
axios.interceptors.response.use(null, function (error) {
// some logic
return Promise.reject(error);
});
Thank you all so much for your help.
You can just check for errors like so:
if(err.response.data.errors){
this.errors = err.response.data.errors;
}
this.errors would be an array you can loop through using v-for to display it

Catching errors with axios

I can not catch the error response with axios. How to do that?
I use something like:
axios
.post(...)
.then(response => {
console.log('Success: ', response)
}).catch(error => {
console.log('Error: ', error)
})
I see that the result of ajax request has 400 status code and the response body looks like {someField:["This field may not be blank"]} (Django backend). That's ok, I'm ready to process these errors in the catch handler.
But they go to the success handler instead. Why so? I see the following output in the console:
Success: Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
The success handler receives axios error object as the result. Why that may be and what to do next? This error object does not contain any usefull information.
UPD. Actually, the error object does contain the useful information, it contains the response object inside. So we can use:
axios
.post(...)
.then(response => {
if (response && response.response) {
console.log('This is also an error', response.response.status)
} else {
console.log('Success: ', response)
}
}).catch(error => {
console.log('Error: ', error)
})
But that looks super ugly.
The axios version is axios#0.16.2.
That's the big project, but I can not find any axios customizations.
Use Axios interceptors for the response. Check which status you want to force to fail as error so they go through the catch path whenever you receive said status code.
axios.interceptors.response.use(function (response) {
if (response.status === 400) {
return Promise.reject(response);
}
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
If you are not receiving the expected status code, you might change the way you check the response in the interceptor. You can check any of the elements that Axios response is structured.
axios.interceptors.response.use(function (response) {
if (response.statusText !== 'OK') {
return Promise.reject(response);
}
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});

Can't access laravel response from ajax library

// Edit: Hm...this is an firebug bug in firefox. On chrome it works...
I'm using Laravel 5.3 with Vue 2.0 and the axios ajax library.
Here is a test controller, where i return a response from laravel:
public function testMethod() {
return response('this is an error', 500);
}
Here is my ajax call:
http(`fetch-data`).then(response => {
const data = response.data;
console.log(data);
}).catch(error => {
console.log(error); // <- This doens't work, he show my nothing
alert(error);
});
The problem is, i need the error message which is returned from laravel into my client catch. But if i console.log them, he show me nothing. If i alert the error, he gives me the following message: Error: Request failed with status code 500.
Why can't i access something like error.statusCode, error.statusMessage?
Try
return response()->json('this is an error', 500);

Resources