1

I am new to angular, trying to call web API from angular. I am facing a very different problem that the response is getting empty array. Here, I have added my service.ts code:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { GroupResult } from '@progress/kendo-data-query';
import { throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';


class TodoListModel{
  id?:number | null;
  itemName!:String;
  dueDate!:Date;
}

@Injectable({
  providedIn: 'root'
})
export class TodoService {


  public initDueTime: Date = new Date(2021, 12, 31, 23, 59, 59);
  public hourlyTodos: ToDo[] | GroupResult[] =[];
  
  todos:ToDo[] = []

  constructor(private http: HttpClient) { }
  
  readonly rootUrl=`https://localhost:44353/api`;
  private todoListModel: TodoListModel[] | JSON=[];
  
  refreshList(){
     //this.http.get(this.rootUrl+"/todos").toPromise().then(res=>this.todoListModel=res as TodoListModel[]);
     this.http.get<TodoListModel[]>(this.rootUrl+`/todos`).pipe(
       map((data: TodoListModel[])=>{
         return data;
       }),
       catchError(error=>{
         return throwError(`Something's wrong`);
       })
     )
     console.log(this.todoListModel);
  }
}

export interface ToDo{
  item:string;
  due:Date;
  hour:number;
}

There's one error that is related to animations, that should not bother.

And my console looks like this: empty array:

enter image description here

2 Answers 2

1

You don't ask a specific question, but based on your tittle, you just should need this (map is not needed):

refreshList(){
   this.http.get<TodoListModel[]>(this.rootUrl+`/todos`)
   .pipe(
       catchError(error=>{
         return throwError(`Something's wrong`);
       })
     )
   .subscribe( (res:TodoListModel[]) => {
                         this.todoListModel = res;
                         console.log(this.todoListModel);
   });
    
  }

I rather deal errors in this way, but it's not needed:

refreshList(){
   this.http.get<TodoListModel[]>(this.rootUrl+`/todos`)
   .subscribe( 
      (res:TodoListModel[]) => {
         this.todoListModel = res;
         console.log(this.todoListModel);
      },
      (error) => throwError(`Something's wrong`);
    );
}
Sign up to request clarification or add additional context in comments.

6 Comments

refreshList(){ this.http.get<TodoListModel[]>(this.rootUrl+/todos) .pipe( catchError(error=>{ return throwError(Something's wrong); }) ) .subscribe( (res:TodoListModel[]) => { this.todoListModel = res; console.log(this.todoListModel); }); console.log(this.todoListModel); } } console log inside subscribe function works but not outside, how's that possible?
Because you get the data asynchronously, and if you left the console.log() outside, when the execution gets to console.log(), it doesn't have data yet. ( if it is outside subscibe, you get to it before todoListModel makes the assignment (this.todoListModel = res;)
refreshList(){ this.http.get<TodoListModel[]>(this.rootUrl+/todos) .pipe( catchError(error=>{ return throwError(Something's wrong); }) ) .subscribe( (res:TodoListModel[]) => { this.todoListModel = res; console.log(this.todoListModel); }); console.log(this.todoListModel); } } here in this code snippet, console.log(this.todoListModel) is returning an empty array when outside subscribe method. why? Please elaborate on the problem and give me the solution.
I already told you the reason: You think that console.log() outside the subscribe is running at the end, after the subscribe, but it doesn't, because you are working wiht async methods. Check by yourself: put console.log("1"); inside the subscribe, and console.log("2"); outside (at the end).Run the code and your are gona see in the console, first "2" and then "1". I hope this helps you to understand the why.
How can I not async methods that is have sync methods?
|
1

To fix this issue you need to alter your pipe/map by assigning the data(data: TodoListModel[]) to this.todoListModel as below:

this.http.get<TodoListModel[]>(this.rootUrl+`/todos`).pipe(
  map((data: TodoListModel[])=>{
    this.todoListModel = data;
  }), catchError(error=>{
    return throwError(`Something's wrong`);
  }) 
)

I have modified the code which you have mentioned:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { GroupResult } from '@progress/kendo-data-query';
import { throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';


class TodoListModel{
  id?:number | null;
  itemName!:String;
  dueDate!:Date;
}

@Injectable({
  providedIn: 'root'
})
export class TodoService {


  public initDueTime: Date = new Date(2021, 12, 31, 23, 59, 59);
  public hourlyTodos: ToDo[] | GroupResult[] =[];
  
  todos:ToDo[] = []

  constructor(private http: HttpClient) { }
  
  readonly rootUrl=`https://localhost:44353/api`;
  private todoListModel: TodoListModel[] | JSON=[];
  
  refreshList(){
     this.http.get<TodoListModel[]>(this.rootUrl+`/todos`).pipe(
       map((data: TodoListModel[])=>{
         this.todoListModel = data;
       }),
       catchError(error=>{
         return throwError(`Something's wrong`);
       })
     )
     console.log(this.todoListModel);
  }
}

export interface ToDo{
  item:string;
  due:Date;
  hour:number;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.