1

`Hi, I need some help to get JSON data from web API on Visual Studio 2015 .net Core, Angular 2 & Typescript. Angular2 folders in /wwwroot/libs.

I'm using Angular 2's http.get(). The result of the get() function display an undefined value ... Why?

There's my files :

Folders

[API][2]

CustomersController.cs => Access OK via http://localhost:45149/api/customers/ => [{...},{...},{...}]

public class CustomersController : Controller
{
    // GET: api/customers 
    [HttpGet]
    public IList<Customer> Get()
    {
        var objects = new List<Customer>
        {
            new Customer { Id = 1, Log = "user01", Name = "user1" },
            new Customer { Id = 2, Log = "user02", Name = "user2" },
            new Customer { Id = 3, Log = "user03", Name = "user3" }
        };
        return objects;
    }
}

customer.ts

export class Customer {
constructor(
    public Id: number,
    public Log: string,
    public Name: string
    ){}
}

customer.service.ts

import { Injectable } from "@angular/core";
import { Http } from "@angular/http";
import { Observable } from "rxjs/Observable";
import { Customer } from "./customer";
import "rxjs/Rx"

@Injectable()
export class CustomerService {
private baseUrl = "http://localhost:45149/api/customers/";  // web api URL
constructor(private http: Http) { }

getCustomers() {
    return this.http.get(this.baseUrl)
        .map(res => <Customer[]> res.json())
        .catch(error => {
            console.log(error);
            return Observable.throw(error);
        });
}}

customer.component.ts

import { Component, OnInit } from '@angular/core';
import { HTTP_PROVIDERS } from '@angular/http';
import { Customer } from './customer';
import { CustomerService } from './customer.service'

@Component({
selector: 'app-api',
template: ` 
<ul class="">
<li *ngFor="let customer of customers">
<span class=""> 
{{customer.Id}} </span> {{customer.Name}}
</li>
</ul>`,
    providers: [
            HTTP_PROVIDERS,
            CustomerService
    ] }) 

    export class CustomerComponent implements OnInit{
    api: string;
    public customers: Customer[];

    constructor(private customerService: CustomerService) {
    this.api = "API Customers"; 
}

ngOnInit() {
    this.customerService.getCustomers()
        .subscribe(
        customers =>
        {
            console.log(this.customers);
            this.customers = customers;
        },
        error => alert("error"));
}}

app.module.ts

// 
*** Imports ***
//

@NgModule({
imports: [BrowserModule, routing], //other modules the app depends on
providers: [CustomerService],
declarations: [AppComponent,
HomeComponent,UploadComponent,CustomerComponent],
bootstrap: [AppComponent] // root component to bootstarp
})

export class AppModule { }

app.component.ts

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

@Component({
selector: 'app-root',
templateUrl: './app/app.component.html' // => SPA
})

export class AppComponent {
title = "App-root"
}

Thank you.

amin89
  • 558
  • 1
  • 8
  • 26
  • 1
    You can see the "GET" request on your network tab in developer tools on your browser?? if not try import the "HttpModule" in ngModule and remover "HTTP_PROVIDERS" – Odysseas Ioannou Dec 09 '16 at 14:52
  • I don't see the Get Request in the network tab (inspect elements => network) ... All what I see is the response of my Http get() which can reach the URL but Nothing in the value => undefined and when I initialize the value of customers to customers: Customer[] = []; The value is "array[0] – amin89 Dec 09 '16 at 15:00
  • 1
    The log statement is currently before the assignment to this.customers. What is logged if you put the log statement after the assignment? – hagner Dec 09 '16 at 15:03
  • @hagner +1 Ok now I have my data in the array : https://imgur.com/a/rYYsN But it seams to be a problem with get() function – amin89 Dec 09 '16 at 15:12
  • 1
    It seems your serializer on the server side return variables in lower case. Either change the serializer setting to use upper case letters or change your view to bind to the lower case properties (customer.name) – hagner Dec 09 '16 at 15:16
  • @OdysseasIoannou Change Nothing. I have 3 objects in the array. How can I do to display the 3 objects ? – amin89 Dec 09 '16 at 15:22
  • @hagner if by "view" you mean modify properties of customer.ts class to lower case values that's what i've done but Nothing change – amin89 Dec 09 '16 at 15:35
  • You also need to change the properties in html specified in the template. Currently it binds to {{customer.Id}} and {{customer.Name}} using first character uppercase, change this to all lowercase – hagner Dec 09 '16 at 15:37
  • @hagner thank u ! it works and u're right all variables of the Customer class should be in lower cases ... Actually if we remove the Customer class it works fine too ... Why should we put one so? – amin89 Dec 09 '16 at 15:43
  • @amin89 I have added this as an answer so we can discuss the solution there – hagner Dec 09 '16 at 15:52

1 Answers1

1

It looks like your server is set to serialize the response with camel-casing while you were trying to bind to properties with upper case names.

If you wish to change your serializer settings to use another format, please check the following article: Web API serialize properties starting from lowercase letter.

Otherwise you should be fine by binding to the lower case names on the angular side

Community
  • 1
  • 1
hagner
  • 1,050
  • 9
  • 12
  • Is it mandatory to create a class or an interface related to the server-side class (api) ? If not, why implement it so? ty – amin89 Dec 09 '16 at 16:04
  • 1
    It is not mandatory to create a class for it if you only wish to display it. If you want to you can use a variable of type: any to get it and then just bind to the correct properties in your template. But as soon as you wish to interact with it in any way in a component or directive, to do things like sorting, filtering or similar you will need a class for it. – hagner Dec 09 '16 at 16:12