Mike
Mike

Reputation: 4091

Angular 2+ http service is being called, but request is not going out

I want to be able to instantiate a model class, but also give it access to services.

For example, say I have these endpoints:

/book/:id
/book/:id/author

I want to have a BooksService service to fetch a list a Book instance. I'd like the book instances to be instantiated with new, given a definition JSON through the constructor, while still being able to use Angular dependencies.

Example of what I want to do:

BooksService.getBook(1)       // makes call to /book/1
    .subscribe((book) => {
        book.getAuthor()  // makes call to /book/1/author
        ...
    });

To accomplish this, I tried to use a factory to new an instance of a book model. I then pass in a reference to the Http injected dependency that the factory injects.

Here's what I have:

BooksService

@Injectable()
export class BookService {
    constructor(
        private http: Http,
        private bookModelFactory: BookModelFactory
    ) {}

    getBook(): Observable<BookModel> {
        return this.http.get('http://localhost:3000/book/1')
            .map((res) => {
                return this.bookModelFactory.make(res.json().data);
            });
    }
}

BookModel, BookModelFactory

@Injectable()
export class BookModelFactory {
    constructor (private http: Http) {}

    make(def: object): BookModel {
        var book = new BookModel(def);
        book.http = this.http;
        return book;
    }
}

export class BookModel {
    def: any;
    http: Http;

    constructor (def: object) {
        this.def = def;
    }

    getAuthor() {
        console.log('http', this.http);
        this.http.get('http://localhost:3000/book/1/author');
    }
}

When I try to use this code, I see the console log for the http object in book.getAuthor(). It exists, and I can see the get method on it. But it never makes the API request. Nothing in the network tab has anything about a call to /book/1/author. There are no errors. Simply put, nothing happens.

Why isn't the request being made when this.http.get('...') is being called in getAuthors()?

Thanks in advance.

Using Angular 4.

(Imports statements are removed for brevity)

Upvotes: 0

Views: 363

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

2) If this is a good strategy... why isn't the request being made when this.http.get('...') is being called in getAuthors()?

Because no-one ever subscribed to the results of this call:

this.http.get('http://localhost:3000/book/1/author').subscribe(res => {
    // do something with the results here
});

In angular if you do not subscribe to the results of the HTTP call, then this call will never be made.

Or maybe you want your getAuthor method to return an Observable<Author> so that it is the caller of this method that can subscribe to the results:

getAuthor(): Observable<Author> {
    return this.http.get('http://localhost:3000/book/1/author').map(res => {
        return res.json().data;
    });
}

So that you can subscribe to it later:

BooksService.getBook(1)       // makes call to /book/1
    .subscribe(book => {
        book.getAuthor() // makes call to /book/1/author
            .subscribe(author => {
                // do something with the book author here
            });
        ...
    });

So remember, if you do not subscribe, the AJAX call will not be made.

Upvotes: 3

Related Questions