Search code examples
javascriptangularhttpexpressget

How do I get data to display in Angular from API in Express?


I am trying to use Nodejs/Express as my back end for producing data from a database. I currently have an api route setup so that a database query will result in its directory. So if I visit localhost:3000/api currently I will see the following:

{"status":200,"data":[{"Issuer_Id":1,"Data_Id":2,"Data_Name":"Name 1"},{"Issuer_Id":2,"Data_Id":14,"Data_Name":"Name 2"},{"Issuer_Id":2,"Data_Id":1,"Data_Name":"Name 3"}],"message":null}

This leads me to believe I have everything setup correctly on the back end.

Now how do I get this data to display on my Angular front end?

I have been through hours of tutorials and this is what I have come up with:

nav.component.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from '../../data.service';
import { Series } from '../../data.service';
import {Observable} from 'rxjs/Rx';

@Component({
  selector: 'app-fixed-nav',
  templateUrl: './fixed-nav.component.html',
  styleUrls: ['./fixed-nav.component.css']
})
export class FixedNavComponent implements OnInit{
  serieses: Series[] ;

constructor(private dataService: DataService) {}

ngOnInit() {
  this.dataService.getSeries().subscribe((serieses: Series[]) => this.serieses = serieses);
}
}

data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from'@angular/common/http';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/toPromise';

export class Series {
  Issuer_Id: number;
  Data_Id: number;
  Data_Name: string;
}


@Injectable()
export class DataService {
  constructor(private _http: Http) {}

  getSeries(): Observable<Series[]> {
    return this._http.get("http://localhost:3000/api/")
    .map((res: Response) => res.json());
  }
}

app.module.ts

import { Form1Module } from './modules/form1/form1.module';
import { FixedNavModule } from './modules/fixed-nav/fixed-nav.module';
import { HeaderModule } from './modules/header/header.module';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { DataService } from './data.service';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,           
    HttpClientModule,
    HeaderModule,
    FixedNavModule,
    Form1Module,
    NgbModule.forRoot()
  ],
  providers: [DataService],
  bootstrap: [AppComponent]
})
export class AppModule { }

What do I need to enter in the nav.component.html to see the results?

Also note that when I refresh my angular page on lcoalhost:4200 I can see that the GET request is hitting the /apiu/ on the 3000 express server.


Solution

  • I am trying to help with best practices which might help get the intended result. I will amend this answer as we troubleshoot and hopefully arrive at the right answer.

    So in your dataServices service I wanted to point out a couple things. Angular recommends we use the httpClient and not http and warn that http will soon be depreciated. I am fairly new to angular myself and have only ever used httpClient and have gotten great results so I recommend using that. I think this means that the promise that you are returned is changed too. Namely, you pust use a .pipe method inorder to use rxjs operators like map on the result. So this is what your dataService file would look like:

    import { Injectable } from '@angular/core';
    import { HttpClient } from'@angular/common/http';
    import { Http, Headers, RequestOptions, Response } from '@angular/http';
    import { Observable } from 'rxjs/Observable';
    
    import { map } from 'rxjs/operators';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/observable/throw';
    import 'rxjs/add/operator/do';
    import 'rxjs/add/operator/toPromise';
    
    export class Series {
      Issuer_Id: number;
      Data_Id: number;
      Data_Name: string;
    }
    
    
    @Injectable()
    export class DataService {
      constructor(private _http: HttpClient) {}
    
      getSeries(): Observable<Series[]> {
        return this._http.get<Series[]>("http://localhost:3000/api/")
        .pipe(
          map((res) => {
            console.log(res);
            return <Series[]> res
          })
        )
      }
    }
    

    Note that I have imported map in a different rxjs/operators. In actuality you dont even need to pipe or map the return since you have already declared the type of return in the get method of _http. HttpClient will cast the return into a Series[] for you so this one liner: return this._http.get("http://localhost:3000/api/") would work. I've written the code how it is however to console.log the return that your getting.

    In the comments, could you tell me what is logged?