Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Angular Basics Services in Angular Connecting a Service and Component

Linda de Haan
Linda de Haan
12,413 Points

Using Angular HttpClientModule instead of HttpModule

As of Angular 4.3.x and above, HttpClientModule is available. In the future HttpModule with its Http class will be deprecated. Using the photoblog app from the course as an example, I created my own Angular CLI app where users can post a message. I'm trying to update the my app with the new HttpClientModule. I'm stuck at the response.json() method used in the PostService. Apparently json is a default in the new HttpClientModule, so you have to delete that. But I don't understand what to replace it with. I've searched online, but all the examples don't look like anything from this course and are way too complicated. I'm just starting with Angular :(

This is the code from this course. In the app.module.ts file you have to replace the imports:

// import { HttpModule } from '@angular/http';  // this is going to be replaced with this:
import { HttpClientModule } from '@angular/common/http';

@NgModule({
    imports: [
        // HttpModule,  // this is going to be replaced with this:
        HttpCliendModule,
    ],

Then in the PostService there are replacements as well and then there's the http.get() method with the response.json() method that needs to change, but I don't know how:

import { HttpClient } from '@angular/http';  // <-- HttpClient instead of Http

@Injectable()
export class PostService {
    constructor(private http: HttpClient) {  // <-- HttpClient instead of Http
    }
    getPosts(): Promise<Post[]> {
        return this.http.get('/app/posts')
                .toPromise()
                .then(response => response.json().data as Post[]); // <-- now the .json() says: Property 'json' does not exist on type 'Object'   How to change this so it works with the new HttpClient?
    }
}

Also in the newsfeed.component.ts file it gets and shows the posts from the backend. Does anything need to change here as well?

import { Component, OnInit } from '@angular/core';
import { PostService } from '../shared/post.service';
import { Post } from '../shared/post.model';

@Component({
    // selectors and templates
}) 

export class NewsfeedComponent implements OnInit {
    posts: Post[];
    constructor(private postService: PostService) {    
    }

    ngOnInit() {
        this.postService
            .getPosts()
            .then(posts => this.posts = posts);  // does this need to change?
    }
}

I know it's probably difficult to help without the entire code, but please try? I'll add more code if needed.

1 Answer

Linda de Haan
Linda de Haan
12,413 Points

I finally figured it out. For other students, I'll add what I know. I found these tutorials explaining GET and POST requests with HttpClient:

This is the new (still very basic) code to get the data from the backend. The backend (backend.ts) looks like this:

import { InMemoryDbService } from 'angular-in-memory-web-api';

declare var file: any;

export class InMemoryPostService implements InMemoryDbService {
    createDb() {
        let posts = [
            {
                id: 1,
                author: 'Jessica Jones',
                date: '1 hour ago',
                posts: [
                    {
                        id: 1,
                        post: 'I like penguins'
                    }
                ]
            },
            {
                // more posts
            },
        ];
        return { posts };
    }
}

Then the GET request in the service (post.service.ts) looks like this:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders  } from '@angular/common/http';

// some imports included for the get request, because HttpClient uses RxJS code, 
// including error handling and Observables
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { catchError, map, tap, retry } from 'rxjs/operators';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

import { Post } from '../_models/index';

@Injectable()
export class PostService {
    private postsUrl = 'api/posts';  // URL to web api

    constructor(private http: HttpClient) { }

    /** GET posts from the server */
    getPosts(): Observable<Post[]> {
        return this.http.get<Post[]>(this.postsUrl)  // this is all you need to get the data from the backend
            .map((data:Post[]) => {    
                        return data;
                    })
// Some APIs may bury the data that you want within an object. 
// So you might have to dig that data out by processing the Observable result with the RxJS map operator.
    }
}
// there are other methods, like catch to handle errors and interceptors that you can use on the GET request, 
// but I'm not going too much into detail here. It's all explained in the tutorial links above.

Finally in the newsfeed.component.ts where I want to pass the data into the view, you need to add a function called subscribe()

export class NewsfeedComponent implements OnInit {
  posts: Post[];
    constructor(private postService: PostService) { }

    ngOnInit() {
        this.postService.getPosts().subscribe(posts => this.posts = posts);
       // you need to add subscribe, or else nothing will happen
    }

}

That's it. Took me a while to figure this out on my own. I think the Angular course on Treehouse could do with an update or a little more in depth tutorials. Especially on subjects like GET/POST etc.