0

I have to make a project with angular 4.

I have a web application that return me a json file like this :

{
  "Microsoft ": {
     "name1": [
        "link1",
        "link2",
        "link3"
    ],
     "name2": [
        "link1",
        "link2"
    ],
     "name3": [],
     "name4": [],
     "name5": [
        "link1"
    ]
  }
}

And I would like to display this file with angular but I have 2 problems,

I don't know how to manipulate json with angular and I don't know why the MicrosoftResult is empty?

This is my component :

import { Component, OnInit } from '@angular/core';
import {MicrosoftService} from './microsoft.service';
import {MicrosoftResult} from './microsoft-result';
import {Observable} from 'rxjs/Observable';
import {Photos} from './photos';

@Component({
  selector: 'app-microsoft',
  templateUrl: './microsoft.component.html',
  styleUrls: ['./microsoft.component.css']
})
export class MicrosoftComponent {

  constructor(private microsoftService: MicrosoftService) {
  }

  microsoftResult: MicrosoftResult;

  getJson(): void {
    this.microsoftService.getJson()
      .subscribe(
    data => this.microsoftResult = data,
        error => console.log('Error :: ' + error)
      );
  }
}

And my service :

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { MicrosoftResult } from './microsoft-result';
import {catchError} from 'rxjs/operators';
import {Observable} from 'rxjs/Observable';
import {of} from 'rxjs/observable/of';
import 'rxjs/add/operator/map';

@Injectable()
export class MicrosoftService {

  apiUrl = 'http://localhost:8080/test/';

  constructor(private http: HttpClient) { }

  getJson(): Observable<any> {
    return this.http
      .get(this.apiUrl)
      .map((res: any) => res.json());

  }
}

And this is the microsoft result interface :

export interface MicrosoftResult {
Microsoft: JSON;
}

Then this is the html website :

<label>Utilisation d'un get : </label>
<button (click)="getJson()">Get</button>
<p>{{microsoftResult.Microsoft}}</p>

But the problem is when I open the page on the browser I have an error on the console when i open the website and when i click on the button :

ERROR TypeError: Cannot read property 'Microsoft' of undefined
    at Object.eval [as updateRenderer] (MicrosoftComponent.html:14)
    at Object.debugUpdateRenderer [as updateRenderer] (core.js:14693)
    at checkAndUpdateView (core.js:13807)
    at callViewAction (core.js:14153)
    at execComponentViewsAction (core.js:14085)
    at checkAndUpdateView (core.js:13808)
    at callViewAction (core.js:14153)
    at execComponentViewsAction (core.js:14085)
    at checkAndUpdateView (core.js:13808)
    at callWithDebugContext (core.js:15056)
yoyozaza
  • 1
  • 3

3 Answers3

0

Try using the ?. (safe navigation operator) on the microsoftResult object in the template.

<p>{{microsoftResult?.Microsoft}}</p>
Matt
  • 2,096
  • 14
  • 20
0

I suggest you to cast to response to a specific object and check the response.json().data in your code like in this part of the angular tutorial v4: https://v4.angular.io/tutorial/toh-pt6

private heroesUrl = 'api/heroes';  // URL to web api

constructor(private http: Http) { }

getHeroes(): Promise<Hero[]> {
  return this.http.get(this.heroesUrl)
             .toPromise()
             .then(response => response.json().data as Hero[])
             .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);
}
Jorge Tovar
  • 1,374
  • 12
  • 17
0

There are several improvements need to be done in your code like :-

1) The expected JSON that you have written has "Microsoft " not "Microsoft" but I think it might be a typo from your side.

2) ERROR TypeError: Cannot read property 'Microsoft' of undefined. This error is thrown because when your HTML is rendering, the value of microsoftResult is actually undefined because you have not initialized this with default value.

3) In your function, assign the Microsoft property if it exists i.e

getJson(): void {
    this.microsoftService.getJson().subscribe(
        data => {
            if(data.Microsoft){
                 this.microsoftResult.Microsoft = data.Microsoft;
            } else { 
                 // Something else
            }
        },
        error => console.log('Error :: ' + error)
     );
  }
AmitKhiwal
  • 59
  • 6
  • thank you for your response but i have another error, `Error :: TypeError: res.json is not a function` – yoyozaza Mar 23 '18 at 10:47
  • You don't need to use `.json()` as you are using **HttpClient**. Check this [link](https://stackoverflow.com/a/46630922/7265553) – AmitKhiwal Mar 23 '18 at 10:52
  • I got the object and it's work but i don't know how to extract the value of "Microsoft" from the json returned by the get and assign it to the Microsoft attribute of the MicrosoftResult ... sorry for my english :( – yoyozaza Mar 23 '18 at 11:18
  • And the microsoftResult stay empty – yoyozaza Mar 23 '18 at 16:03