I have an Angular (12.2.11) application consisting of
- AppComponent
- CarsComponent
I have implemented routing in my AppModule
as:
const routes: Routes = [
{path: 'cars', component: CarsComponent},
];
I make API call with my `CarsService" and I get list of cars, so all that works fine.
But in AppComponent, I would like to make call to /about
endpoint to get the version of API and that is not working. My /about
endpoint returns version of my API and I confirmed that in PostMan. This is what I am doing:
Created AboutService:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AboutService {
private baseUrl = "http://localhost:8080/myapi/v1/about";
constructor(private httpClient: HttpClient) { }
getAbout(): Observable<string> {
return this.httpClient.get<string>(`${this.baseUrl}`);
}
}
Then in my AppComponent, I implemented OnInit, injected HttpClient like:
import { Component, OnInit } from '@angular/core';
import { AboutService } from './services/about/about.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'My Angular App';
about: string;
constructor(private aboutService: AboutService) {}
ngOnInit(): void {
this.getAbout();
}
private getAbout() {
this.aboutService.getAbout().subscribe(data => {
this.about = data;
console.log(data);
},
error => {
console.log(error);
});
}
}
And finally, in my AppComponent html template:
<footer >
<div >
<span>{{about}}</span>
</div>
</footer>
The about
information will not show. If I put some hardcoded text in the above span
, the text will show. I added console.log()
calls in above getAbout()
to log received data but I dont see any log statements for that call. Also no error is logged. So, I guess it might be that routhing prevents execution of this method entirely.
How do I fetch data from app.component
for above scenario?
UPDATE 1:
Updated above calls to console.log() to log received response data or error. It discovered that what I am getting is text rather than JSON and I think that is why nothing shows:
error:{error: SyntaxError: Unexpected token i in JSON at pos…
error:SyntaxError: message: 'Unexpected token i in JSON at position 0'}
text:'myapi v.1.0.0\nJdk v.11.0.10\nSpringboot v.5.3.9'
message:'Http failure during parsing for http://localhost:8080/myapi/v1/about'
As I am not planning to return JSON for /about endpoint but rather just plain text, is there a way to deal with this and get that text?
CodePudding user response:
I would suggest you to use AsyncPipe. So It could be like: app.component.ts:
import { Component, OnInit } from '@angular/core';
import { AboutService } from './services/about/about.service';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'My Angular App';
about$: Observable<string>;
constructor(private readonly aboutService: AboutService) {}
ngOnInit(): void {
this.getAbout();
}
private getAbout(): void {
this.about$ = this.aboutService.getAbout();
}
}
app.component.html:
<footer >
<div >
<span>{{ about$ | async }}</span>
</div>
</footer>
Relating the issue - did you output something in console.log()
? because in provided code no parameters passed. Did you try putting breakpoints on that lines?
UPDATE:
To get text from HTTP call, you just need to set Content-Type
header and responseType: 'text'
:
getAbout(): Observable<string> {
return this.httpClient.get<string>(`${this.baseUrl}`, {
headers: new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8'),
responseType: 'text'
});
}
CodePudding user response:
Thanks to @anjs and @RuslanLekhan whose comment and answer above helped me pinpoint where I was making the mistake.
I changed the respected API method to return JSON object instead of string and modified code as:
export class AboutService {
private baseUrl = "http://localhost:8080/myapi/v1/about";
constructor(private httpClient: HttpClient) { }
getAbout(): Observable<About> {
return this.httpClient.get<About>(`${this.baseUrl}`);
}
}
Above, About
is model containing information about the api such as api version returned from api as JSON object.
export class AppComponent implements OnInit {
title = 'My Angular App';
about: About;
constructor(private aboutService: AboutService) {}
ngOnInit(): void {
this.getAbout();
}
private getAbout() {
this.aboutService.getAbout().subscribe(data => {
this.about = data;
console.log(data);
},
error => {
console.log(error);
});
}
}
And finally in template footer:
<footer >
<div >
<span>{{about.apiVersionNumber}}</span>
</div>
</footer>