18

I am very new to Angular2 and trying to build up a Todo app.

Here's my file structure:

My file structure

My todo.service.ts code (inside shared folder)

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';

import 'rxjs/add/operator/toPromise';

import { ITodo } from './todo.model';

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

 getTodos(): Promise<ITodo[]> {
    return this.http.get('api/todos')
            .toPromise()
            .then(res => res.json().data)
            .catch(this.handleError); 
}

addTodo(todo: ITodo): Promise<ITodo> {
    return this.post(todo);
}

deleteTodo(todo: ITodo): Promise<ITodo> {
    return this.delete(todo);
}

private post(todo: ITodo): Promise<ITodo> {
    let headers = new Headers({
        'Content-Type': 'application/json'
    });

    return this.http.post('api/todos', JSON.stringify(todo), { headers })
    .toPromise()
    .then(res => res.json().data)
    .catch(this.handleError)
}

private delete(todo: ITodo): Promise<ITodo> {
    let headers = new Headers({
        'Content-Type': 'application/json'
    });

    let url = `api/todos/${todo.id}`;

    return this.http.delete(url, { headers })
    .toPromise()
    .then(res => todo)
    .catch(this.handleError)
}

private handleError(error: any): Promise<any> {
    console.log('The error occured >>>', error);
    return Promise.reject(error.message || error);
  }
}

My main.ts code

import { bootstrap }    from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS, XHRBackend } from '@angular/http';
import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory- web-api'; 
import { TodoSeedData } from './shared/todo.data';

import {AppComponent} from './app.component';

bootstrap(AppComponent,[
  HTTP_PROVIDERS,
  { provide: XHRBackend, useClass: InMemoryBackendService },
  { provide: SEED_DATA, useClass: TodoSeedData },
 ]);

Everything had been working without errors till I needed http.

Found sort of similar problem here

but it is not working to me.

Console.log shows error: Collection 'todos' not found. Console image

I guess it's an issue with http. Please, help.

Community
  • 1
  • 1
Alexandr Belov
  • 1,804
  • 9
  • 30
  • 43
  • This looks like an issue with your get request. I would put a breakpoint on `return this.http.get('api/todos')`. Hit F11 to step into the function. And then inspect `url` of this function. `Http.prototype.get = function (url, options) { };` Make sure url is what you think it should be. If you evaluate in console and click on the link it should open in a new tab with the json object you are expecting. – khollenbeck Aug 22 '16 at 19:57
  • Did you ever figure this out? I have a similar issue with a WebAPI call - the URL is correct but it's giving this same error – Rodney Nov 09 '16 at 21:07

5 Answers5

42

I had a similar issue calling my WebAPI. In the end I had to comment out the InMemoryDataService - as soon as I did this then the error went away and I was able to hit my WebAPI: AngularJS 2 : Getting data from json file not working

Community
  • 1
  • 1
Rodney
  • 5,417
  • 7
  • 54
  • 98
12

This appears to be an issue when using the InMemoryDataService for the InMemoryWebApi (to mock your actual back end api) and not with the Angular2 Http. You can confirm this by turning off the in memory web api in your app.module.ts and see if the http calls then successfully hit your API.

The createDb() method in your InMemoryBackendService should look something like this for it to work.

export class InMemoryBackendService implements InMemoryDbService {
createDb() {
   let todos = <object>,
   todos2 = <object>;        <==== collection todos is defined here...
   return {todos,todos2};    
 }
}

Replace with your mock data objects.
See the documentation for in memory web api here

Olubisi
  • 121
  • 1
  • 4
6

I had also the same propblem I had commented out the InMemoryWebApiModule.forRoot(InMemoryDataService) in my Module and its working fine for me

Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70
2

This may help some folks who find themselves here. There is a configuration option to pass through to a live server if the collection isn't configured:

passThruUnknownUrl: true

see https://github.com/angular/in-memory-web-api#pass-thru-to-a-live-server

pxp
  • 61
  • 2
0

As mentioned by @pxp, you can use the passThruUnknownUrl in the In Memory Database configuration and the URLs not known by the In Memory Database will be allowed to continue, like so,

In your app.module.ts file:

imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    ReactiveFormsModule,
    InMemoryWebApiModule.forRoot(AppData, { delay: 1000, passThruUnknownUrl: true }),
],
Latin Warrior
  • 902
  • 11
  • 14