1

I write my first Angular App and I want to get Data from another API Rest available in local.

My work based on Angular tuto tour-of-heroes. I use a component service for calling my API and return result in another component. I don't know how debug correctly in Angular. My API Rest run correctly and return data if call with my browser.

My component datatable (which display return data API) run correctly and display HTML but not the *ngFor part (tr table for each data).

If you have a trick for helping debug or find where is error...

app.component.ts

import {Component} from '@angular/core';

@Component({
    selector: 'app-my-app',
    template: `
        <h1>fzfzefzfzefz</h1>
        <nav>
        </nav>
        <app-my-datatable></app-my-datatable>
        <!--<router-outlet></router-outlet>-->
    `,
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    title = 'blablabla';
}

app.module.ts

import { BrowserModule }      from '@angular/platform-browser';
import { NgModule }           from '@angular/core';
import { FormsModule }        from '@angular/forms';
import {Router, RouterModule} from '@angular/router';

import { AppComponent }       from './app.component';
import { DatatableComponent } from './datatable.component';
import { OperationService }   from './operation.service';

import { AppRoutingModule }   from './app-routing.module';
import { HttpModule }         from '@angular/http';

@NgModule({
  declarations: [AppComponent, DatatableComponent],
  imports:      [
      BrowserModule,
      FormsModule,
      AppRoutingModule,
      HttpModule,
      RouterModule.forRoot([{path: 'datatable', component: DatatableComponent}])
  ],
  providers:    [
      OperationService
  ],
  bootstrap:    [AppComponent]
})

export class AppModule { }

app-routing.module.ts

import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import {DatatableComponent}     from './datatable.component';

const routes: Routes = [
    { path: '', redirectTo: '/datatable', pathMatch: 'full' },
    { path: 'datatable',  component: DatatableComponent },
];

@NgModule({
    imports: [ RouterModule.forRoot(routes) ],
    exports: [ RouterModule ]
})

export class AppRoutingModule {}

datatable.component.html

<h1>efzefzefz</h1>

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>Label</th>
            <th>Cost</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let operation of operations">
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
    </tbody>
</table>

datatable.component.ts

import { Component, OnInit } from '@angular/core';

import { Operation }         from './operation';
import { OperationService }  from './operation.service';

@Component({
    selector: 'app-my-datatable',
    templateUrl: './datatable.component.html',
    styleUrls: ['./datatable.component.css']
})

export class DatatableComponent implements OnInit{

    title = 'app toto';

    operations: Operation[];

    constructor(private operationService: OperationService) { }

    getOperations(): void {
        this.operationService.getOperations().then(operations => this.operations = operations);
    }
    ngOnInit(): void {
        this.getOperations();
    }
}

operations.service.ts

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

import { Operation }        from './operation';

import 'rxjs/add/operator/toPromise';

@Injectable()

export class OperationService
{
    private headers = new Headers({'Content-Type': 'application/json'});
    private operationsUrl = 'http://60.60.60.100/api/operations';

    constructor(private http: Http) { }

    getOperations(): Promise<Operation[]>
    {
        return this.http.get(this.operationsUrl)
            .toPromise()
            .then(response => response.json().data as Operation[])
            .catch(this.handleError);
    }

    getOperation(id: number): Promise<Operation>
    {
        const url = `${this.operationsUrl}/${id}`;
        return this.http.get(url)
            .toPromise()
            .then(response => response.json().data as Operation)
            .catch(this.handleError);
    }

    update(operation: Operation): Promise<Operation>
    {
        const url = `${this.operationsUrl}/${operation.id}`;
        return this.http
            .put(url, JSON.stringify(operation), {headers: this.headers})
            .toPromise()
            .then(() => operation)
            .catch(this.handleError);
    }

    create(name: string): Promise<Operation>
    {
        return this.http
            .post(this.operationsUrl, JSON.stringify({name: name}), {headers: this.headers})
            .toPromise()
            .then(res => res.json().data as Operation)
            .catch(this.handleError);
    }

    delete(id: number): Promise<void>
    {
        const url = `${this.operationsUrl}/${id}`;
        return this.http.delete(url, {headers: this.headers})
            .toPromise()
            .then(() => null)
            .catch(this.handleError);
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

thanks for help.

3
  • Hmm. Maybe this: res.json().data as Operation could be this: res.json() as Operation[]. The .json() method consumes the body of the response, so you don't have to call data unless it's being returned from your API. Commented Oct 27, 2017 at 12:58
  • No difference. I think perhaps a CORS issue... Commented Oct 27, 2017 at 14:00
  • @LenilsondeCastro : My problem has 2 type. A cors config in my API rest (Symfony) and response.json without .data. Can you post a response and I validate this. Thank you Commented Oct 27, 2017 at 14:35

1 Answer 1

1

The .json() method consumes the body of the response, so you don't have to call data unless it's being returned from your API.

So you should switch res.json().data as Operation to res.json() as Operation[].

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.