Angular JWT token parsing to json issue - json

I have validated my JWT on jwt.io
But when i try to parse the response to:
login(model: any) {
return this.http
.post(this.baseURI + 'login', model, this.requestOptions())
.map((response: Response) => {
const user = response.json();
if (user) {
localStorage.setItem('token', user.token);
this.decodedToken = this.jwtHelper.decodeToken(user.token);
console.log(this.decodedToken);
this.userToken = user.token;
}
})
.catch(this.handleError);
}
it throws an error stating:
Error is generated when it tries to parse response to json: response.json();
A little help would be appreciated.

Since the token starts with e and your error states that its getting an unexpected e at position 0 of what it expects to be a Json document, it sounds like you might be getting a response body including the token as raw text, not the Json User object which your code expects.

Related

Angular fails to parse string from api call (web core 3)

Controller code:
[Route("api/[controller]")]
[ApiController]
public class AjaxController : ControllerBase
{
ApplicationDbContext dbContext = null;
public AjaxController(ApplicationDbContext ctx)
{
dbContext = ctx;
}
[HttpGet]
[Route("GetString")]
public string GetString()
{
return "Hello World";
}
[HttpGet]
[Route("GetCategories")]
public Category[] GetCategories()
{
return dbContext.Categories.ToArray();
}
}
Angular code:
http.get<string>(baseUrl + 'api/ajax/GetString').subscribe(result => {
console.log(result);
}, error => console.error(error));
While Angular can parse without error the GetCategories endpoint, it cannot parse the much simpler GetString. Why? The error in the console is:
error: SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
​​text: "Hello World"
I tried wit Postman and the response is just fine, see screenshot:
The issue is your response from GetString is returning just a string of value Hello World as shown by the screenshot from Postman. The GetCategories endpoint must be returning valid JSON if you are getting a valid response.
By default Angular assumes the response type of a HttpRequest to be of type json.
To fix this, specify as the second parameter to http.get() the responseType expected from the server which in your case for the GetString endpoint will be 'text'. So your http.get() call should look like the following:
http.get<string>(baseUrl + 'api/ajax/GetString', { responseType: 'text' }).subscribe(result => {
console.log(result);
}, error => console.error(error));
If your intention was to return valid JSON from GetString then you need to format the response from your server as appropriate.
See the Angular documentation on HttpRequest - responseType. I've included a copy below.
responseType: 'arraybuffer' | 'blob' | 'json' | 'text'
The expected response type of the server.
This is used to parse the response appropriately before returning it to the requestee.

Httpclient request in angular json error

I am doing http client request
export class MapjsonService{
theUrl = 'http://localhost:4200/api/Lat_Long.json';
constructor(private http: HttpClient) { }
fetchNews(): Observable<any>{
return this.http.get(this.theUrl)
}
It is working about 99.99% of the time sadly this is running so often that is fails like once every 10 mins with
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:4200/api/Lat_Long.json", ok: false, …}
and
"Http failure during parsing for http://localhost:4200/api/Lat_Long.json"
Now I figured out for some reason my nrql query from newrelic (which is what is being stored in '/api/lat_long.json' does not have the final closing '}' once every orange moon. and this is what is throwing this error. my question is there any whay for me to check if the returned value is valid json and if it is not try the GET request again without terminating the process that called it. Thx
Your code is throwing an error because the json is not correct, therefore it can't be parsed, and therefore the observable throws an error:
fetchNews(): Observable<any>{
return this.http.get(this.theUrl)
}
By default, the http client expect json because that's usually what users expect from it. It's not always the case, like the situation you are in right now.
We can tell the http client not to parse the json on its own by specifying what we want from it using the {responseType: 'text'} parameter.
fetchNews(): Observable<any>{
return this.http.get(this.theUrl, {responseType: 'text'})
}
But then you need to parse the json when possible. So we will map the observable and parse the content here if possible.
fetchNews(): Observable<any>{
return this.http.get(this.theUrl, {responseType: 'text'}).map(res => {
try{
return JSON.parse(res);
} catch {
return null;
}
})
}
Then do whatever you want, the value returned by the observable will be null if it can't be parsed.
RXJS 6 syntax:
fetchNews(): Observable<any>{
return this.http.get(this.theUrl, {responseType: 'text'}).pipe(
map(res => {
try{
return JSON.parse(res);
} catch {
return null;
}
})
)
}

Unble to Extract the _body response in angular 4 in JSON format

I am using angular 4.2.6 for my application. I have a service like this
checkStaff(email: any) {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email)).map(
(resp) => resp
)
}
checkStaff(email:any){
return
this._http.post(this.url+"/Impsapi/getStaff",JSON.stringify(email)).map(
(resp)=> resp
)
}
this.loginServ.checkStaff(this.user)
.subscribe(
userData => {
this._return = userData;
console.log(this._return);
}
);
The Server returns JSON as response. but when i log the output, i get the below
logged response
please I need to consume the data in the body of the response. I have not been able convert the ._body to a proper json and use for the app. please help
The response data are in JSON string form. The app must parse that string into JavaScript objects by calling res.json().
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email)).map(
(resp) => resp.json()
)
Update
try following code snippet
checkStaff(email: any) {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email))
.map(res => {return res.json()})
}
Try this:
this.loginServ.checkStaff(this.user)
.subscribe(
userData => {
this._return = userData.json();
console.log(this._return);
}
);
I mean your checkStaff:
checkStaff(email: any): Observable<Response> {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email));
}
export classMyResp
{
id: string;
/*so on...*/
}
This will give you the body of response If there is any.
I got my problem solved. My PHP is hosted on wampserver. In a way invalid JSON is always returned when i make call to the server. I had to use the ob_clean() function and everything is fine.

Argument of type 'Response' is not assignable to parameter of type 'string'

I have this project I am working on.
the idea is to retrieve books from google book API, using angular 4
I am struggling to understand how to read the JSON response, I am still learning Angular.
I was searching the internet and found this source code on GitHub
google bookstore
I am getting the following error
Argument of type 'Response' is not assignable to parameter of type 'string'.
for this line
let bookResponse = JSON.parse(body);
I am not sure if I am doing it the correct way.
appreciate your help
below is my method for send HTTP request.
getBooks(searchparam: any){
let par = new HttpParams();
par.set('q', searchparam);
return this.httpClient.get('https://www.googleapis.com/books/v1/volumes', {
params : new HttpParams().set('q',searchparam)
}).map(
(response: Response) => {
let data = response;
return data;
}
);
}
below is the method to get data from HTTP request and read JSON response
getBook() {
const dataArrya = this.searchForm.get('param').value;
console.log(dataArrya);
this.requestService.getBooks(dataArrya)
.subscribe(
response => {
this.printData(response)
// console.log(this.bookData);
},
(error) => console.log(error)
);
}
private printData(res: Response) {
let body = res;
let books: Array<Book> = new Array<Book>();
let bookResponse = JSON.parse(body);
console.log(bookResponse);
console.dir(bookResponse);
for (let book of bookResponse.items) {
books.push({
title:book.volumeInfo.title,
subTitle: book.volumeInfo.subTitle,
categories: book.volumeInfo.categories,
authors: book.volumeInfo.authors,
rating: book.volumeInfo.rating,
pageCount: book.volumeInfo.pageCount,
image: book.volumeInfo.imageLinks === undefined ? '' : book.volumeInfo.imageLinks.thumbnail,
description: book.volumeInfo.description,
isbn: book.volumeInfo.industryIdentifiers,
previewLink: book.volumeInfo.previewLink
});
}
}
JSON.parse takes a string, but you're passing it an Angular Response, which is an object (not a string). In order to convert an Angular Response to a string, you can call toString on it, like this:
let bookResponse = JSON.parse(body.toString());
As the reference states,
The responseType value determines how a successful response body will be parsed. If responseType is the default json, a type interface for the resulting object may be passed as a type parameter to request().
HttpClient get already parses the response with JSON.parse by default and there is no need to call it twice.
The result is plain object, not Response (it belongs to Http API and can be confused with Response global when not being imported).
The mentioned repository uses Angular 2 and Http, and the code from there isn't suitable here. HttpClient is newer API that was introduced in Angular 4. The main practical difference between Http and HttpClient is that the latter doesn't require to add .map(response: Response => response.json()) to the request.

RestEasy - JSON response - From Angular2 client, how to only get JSON Object

I'm new to REST services, I have an Angular2 client calling a RestEasy JAX-RS service. All I am trying to get is a "Hello World" message in JSON format. I was expecting only a JSON object, but I get my response with the following structure:
_body: "{"message":"Hello World!!"}"
headers: t
ok: true
status: 200
statusText: "OK"
type: 2
url: "http://localhost:8080/helloapp/rest/hello/world"
__proto__: ...
My question is, Is that the way it should be?
I mean, I thought I would be able to access the JSON object straight from the response. Something like
this.service.getHello()
.then( result => {
console.log(JSON.parse(result)); //{message: "Hello World"}
this.message = JSON.parse(result).message;
});
But I actually have to get it from _body:
this.service.getHello()
.then( result => {
this.message = JSON.parse(result._body).message;
console.log(this.message);//Hello World
});
Is it a RestEasy configuration thing, is there a way to change that?
Or
Should I consider that I will always have a field _body in my response with my data, and that's the default response structure?
For eventual consideration, here is my backend code:
HelloWorld Service:
#Path("/hello")
#Produces({ "application/json" })
#Consumes({ "application/json" })
public class HelloWorld {
public HelloWorld() {}
#GET
#Path("/world")
public Message getHello(){
return new Message("Hello World!!");
}
}
My RestEasy version is 3.1.1.Final running in Wildfly 10.1.0.Final
What you're getting back is the Response object from the Http request. This is what all Http operations will return. The easiest way to parse the JSON from that is to just call the json() method on it
this.service.getHello()
.then((res: Response) => {
let obj = res.json();
});
If you want the getHello to just return the object without having to parse it (on the calling client), then you can do it inside the getHello method by mapping it (using the Observable.map operation)
getHello() {
this.http.get(..)
.map((res: Response) => res.json())
.toPromise();
}
As peeskillet says above, you're getting back the entire Response from the request, and while sometimes you may want to examine the headers, perhaps to handle the different return conditions (retry or redirect on 4xx or 5xx responses for example), most of the time we assume a successful request and we just want the payload.
Angular2 encourages the use of Observables, so your service might look something like this:
getHello()
{
return this.http.get(http://localhost:8080/helloapp/rest/hello/world)
}
And your component may look something like this:
data: string;
ngOnInit() {
this.service
.getHello()
.map(response => response.json())
.subscribe (
data => {
this.data = data,
},
err => console.log('Error',err),
() => console.log('data',this.data)
);
}
You call the service, which is an http.get() and returns an Observable object, and we use .map to parse the response as JSON, which also returns an Observable, which we subscribe to.
Subscribe has three callback functions,
.subscribe(success, failure, complete)
In the example above on success we assign the payload - data - to this.data, if the subscribe fails, you log the error, and when it completes, we can do whatever we like, but in this case, we log this.data to the console - that's optional, but I log out the results while developing and then strip them out later.