Home > Mobile >  How to make a call to API from app.component.ts when using routing
How to make a call to API from app.component.ts when using routing

Time:10-25

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>
  • Related