0

My Backend over at localhost:3000/gettreeview returns a JSON object and it needs to be stored in the variable nodes. I tried to accomplish it with the code below but have failed:

import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpHeaders, HttpClient } from '@angular/common/http';
import { catchError, map } from 'rxjs/operators';

@Component({
  selector: 'app-treeview-tab',
  templateUrl: './treeview-tab.component.html',
  styleUrls: ['./treeview-tab.component.scss']
})
export class TreeviewTabComponent implements OnInit {
  constructor(private client: HttpClient) {  }
  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };
  /**
 * Handle Http operation that failed.
 * Let the app continue.
 * @param operation - name of the operation that failed
 * @param result - optional value to return as the observable result
 */
private handleError<T>(operation = 'operation', result?: T) {
  return (error: any): Observable<T> => {

    // TODO: send the error to remote logging infrastructure
    console.error(error); // log to console instead

    // TODO: better job of transforming error for user consumption
    this.log(`${operation} failed: ${error.message}`);

    // Let the app keep running by returning an empty result.
    return of(result as T);
  };
}
 /**
   * Log a failed AviorBackend error.
   * @param message - message of the operation that failed
   */
  private log(message: string) {
    throw new Error(`AviorBackend: ${message}`);
  }


  // should be fetched from API
  nodes = [];
  options = {};
  ngOnInit() {

 //get JSON 
  const API_URL = 'localhost:3000/gettreeview';
  return this.client.get(API_URL, this.httpOptions).pipe(
    map((res: Response) => {
      this.nodes = res || {};
    }),
    catchError(this.handleError())
  );
  }
}

I am getting the following error message:

Type 'Response | {}' is not assignable to type 'any[]'.
  Type 'Response' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more.

UPDATE my template.html:

<tree-root [nodes]="nodes" [options]="options" (click)="test()" class="list-area"></tree-root>
<div id="treeuserdata" class="content-area"> </div>
Munchkin
  • 857
  • 5
  • 24
  • 51

2 Answers2

1

Try:

this.client.get(API_URL, this.httpOptions).subscribe(
  (res) => { this.nodes.push(res) },
  (error) => { this.handleError(); }
);

You also need to remove the return as you aren't returning anything from the ngOnInit() hook.

ruth
  • 29,535
  • 4
  • 30
  • 57
  • `Property 'json' does not exist on type 'Object'.` :/ – Munchkin Feb 26 '20 at 15:54
  • As mentioned in the other answer, new versions of Angular deserializes the content of a response into an object by default. I've updated the answer accordingly. – ruth Feb 26 '20 at 15:57
  • Hm, now I'm getting `The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Type 'Object' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more.` – Munchkin Feb 26 '20 at 15:58
  • Because you are assigning `Object` to array type. You need to push to the array. I've updated the answer. – ruth Feb 26 '20 at 15:59
  • Hm, for some reason the treeview does not appear and there's no error message. Maybe it's not supposed to in OnInit in the first place? – Munchkin Feb 26 '20 at 16:16
  • I do not know how you populate the treeview. There are be no error messages because the data is being saved correctly but it might not be used correctly. – ruth Feb 26 '20 at 17:44
  • How do I debug this? – Munchkin Feb 27 '20 at 15:46
  • It would be helpful to see the structure of your response and the template. Include `console.log(res);` after the line `this.nodes.push(res);`. Open your browser console and post the screenshot here. Also include your template (.html) file in your question. – ruth Feb 28 '20 at 05:35
  • `console.log` prints out the proper Tree Structure. What's the problem with displaying it then? – Munchkin Feb 28 '20 at 08:52
  • I don’t understand what you mean by tree structure. Also the template shows you are using a component with selector ‘tree-root’. So I would need to see the template of that component to understand how the ‘nodes’ array is used. – ruth Feb 28 '20 at 09:00
  • I meant to say array with elements, which Chrome Devtools shows in its proper structure. Tree-root is the plugin's selector if I'm not wrong. – Munchkin Feb 28 '20 at 09:45
  • Could you please say what plugin? – ruth Feb 28 '20 at 09:48
  • I made a quick [stackblitz](https://stackblitz.com/edit/angular-tree-component-u3gmlp-xpskrm) for your problem. It seems `tree-root` doesn't update the template with objects added later to `nodes` variable. – ruth Feb 28 '20 at 10:46
  • [Here](https://angular2-tree.readme.io/docs/async-data-1) is an excellent example from their docs to use async data. If you could not get it working you need to open a new question, because the scope of this question has already been solved. – ruth Feb 28 '20 at 10:52
  • I accepted your answer. I also posted a new question I would be glad if you were to answer it https://stackoverflow.com/questions/60450560/how-to-implement-this-angular-tree-component-async-data-code – Munchkin Feb 28 '20 at 11:19
  • I am currently not in a position to run Angular locally. However, I would say it would serve you better if you tried something on your own and posted your experience implementing your requirement. Then more people would be interested in solving the problem. – ruth Feb 28 '20 at 12:20
0

you need to subscribe to get the results

.json() is not required with new angular versions

return this.http.request(request)
  .pipe(map(res => res) // you can map to anything you want here)
  .subscribe(
    data => console.log(data),
    err => console.log(err),
    () => console.log('yay')
  );
Barkha
  • 702
  • 3
  • 8