3

I've replicated this tutorial https://malcoded.com/posts/angular-backend-express/ to set up an angular app & an express server w/ Node.js

I'm now trying to send a GET request to retrieve an array of objects with the following code:

import { Component, OnInit } from '@angular/core';
import { CatService } from './cat/cat.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'malcodedTutorial';
  constructor(private catSerivce: CatService) { }

  cats = [];

  ngOnInit() {
    const catsObservable = this.catSerivce.getAllCats();
    catsObservable.subscribe((catsData: []) => {
        this.cats = catsData;
    });
    console.log(this.cats);
  }
}

Also, here is the server.js file:

const express = require('express');
const app = express();
const cors = require('cors')

var corsOptions = {
  origin: 'http://localhost:4200',
  optionsSuccessStatus: 200 
}

app.use(cors(corsOptions))

app.listen(8000, () => {
  console.log('Server started!')
});

// GET ALL CATS
app.route('/api/cats').get((req, res) => {
  res.send({
    cats: [{ name: 'lilly' }, { name: 'lucy' }],
  })
})

// GET A SPECIFIC CAT
app.route('/api/cats/:name').get((req, res) => {
  const requestedCatName = req.params['name']
  res.send({ name: requestedCatName })
})

const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.route('/api/cats').post((req, res) => {
  res.send(201, req.body)
})

// UPDATE
app.route('/api/cats/:name').put((req, res) => {
  res.send(200, req.body)
})

// DELETE
app.route('/api/cats/:name').delete((req, res) => {
  res.sendStatus(204)
})

Also, here is my Cat Service:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';

interface Cat {
  name: string;
}

@Injectable({
  providedIn: 'root'
})
export class CatService {
  constructor(private http: HttpClient) {}
  getAllCats(): Observable<Cat[]> {
    return this.http.get<Cat[]>('http://localhost:8000/api/cats');
  }

  getCat(name: string): Observable<Cat> {
    return this.http.get<Cat>('http://localhost:8000/api/cats/' +   name);
  }

  insertCat(cat: Cat): Observable<Cat> {
    return this.http.post<Cat>('http://localhost:8000/api/cats/', cat);
  }

  updateCat(cat: Cat): Observable<void> {
    return this.http.put<void>(
      'http://localhost:8000/api/cats/' + cat.name,
      cat
    );
  }

  deleteCat(name: string) {
    return this.http.delete('http://localhost:8000/api/cats/' + name);
  }
}

When I run the Angular app, the page is displaying as expected, & there are no errors in the console.

There is an empty array being logged to the console, I don't know why the app isn't picking up the cat objects from server.js.

Can someone please tell me where I am going wrong? Much appreciated

user7554035
  • 389
  • 2
  • 5
  • 19

2 Answers2

1

Your code for getting a response from the server is correct. The reason it is logging an empty array is because your console.log is not inside of the subscription. Since the observable is operating asynchronously it is logging before the response is received. If you want it to console.log only after the response is received then move it inside of your .subscribe()

If you change your ngOnInit() to look like this you won't console.log until the response is received so it should not be empty anymore, unless the response doesn't contain any cats.

ngOnInit() {
    const catsObservable = this.catSerivce.getAllCats();
    catsObservable.subscribe((catsData: []) => {
        this.cats = catsData;
        console.log(this.cats);
    });
}

This would also work:

export class AppComponent implements OnInit {
  title = 'malcodedTutorial';
  constructor(private catSerivce: CatService) { }

  cats = [];

  ngOnInit() {
     this.getCats();
  }

  getCats() {
    const catsObservable = this.catSerivce.getAllCats();
    catsObservable.subscribe((catsData: any[]) => {
      this.cats = catsData;
      console.log(this.cats);
    });
  }
}
Derrick Awuah
  • 373
  • 2
  • 5
0

I think you never get data from the server.

in your cat service

import { HttpHeaders } from '@angular/common/http';


getAllCats() {
    const headers = new HttpHeaders({
      'Content-Type':  'application/json',
      'Authorization': `Bearer test}`
    });
    const options = { headers: headers };
    const url     = 'http://localhost:8000/api/cats';
    return this.http.get<Cat[]>(url, options);
}

first, you must ensure that you get some data and the list is not empty in the console.

Else if you get the data, and in your template, there is nothing showing, then try after view init

You must add the ngAfterViewInit

export class AppComponent implements OnInit, AfterViewInit {
  title = 'malcodedTutorial';
  constructor(private catSerivce: CatService) { }

  cats = [];

  ngOnInit() {
     this.getCats();
  }


  ngAfterViewInit() {
    this.getCats();
  }


  getCats() {
    const catsObservable = this.catSerivce.getAllCats();
    catsObservable.subscribe((catsData: any[]) => {
      this.cats = catsData;
    });
    console.log(this.cats);
  }
}
George C.
  • 6,574
  • 12
  • 55
  • 80