0

I am trying to wrap my head around promises and have some issues. I have a JSON array consisting of many entries:

  { "Work Date"  : "08/04/2021"
  , "Work type"  : "Working"
  , "Project"    : "Projectname"
  , "Client"     : "Company"
  , "Employee"   : "John Doe"
  , "Work hours" : "2.5"
  , "Work note"  : "Work notations here"
  , "Task"       : ""
  , "Task Name"  : ""
  , "TaskType"   : ""
  },

In particular am interested to extract the employees to an array. So I can present / format easier. This is my dataProvider Service (Angular) which loads the JSON and provides the data for further usage:

export class DataproviderService {
  effortsList:Effort[]
  employeeList:string[]
  constructor(private http: HttpClient) { }

  getData(){
    return this.http.get<any>("assets/data.json")
    .toPromise()
    .then(res => <Effort[]>res.data)
    .then(data => { 
      data.forEach(employee => this.employeeList.push(employee["Employee"]))
      return this.effortsList = data.slice();
     })
  }
}

Unfortunately this is not working as I imagined. I get an uncaught error:

Uncaught (in promise): TypeError: this.employeeList is undefined

What am I doing wrong? Thank you in advance!

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
Oerf
  • 9
  • 3
  • 2
    You forgot to initlalize employee list as empty array, so your push doesn't work. – ulou May 22 '21 at 11:50
  • sidenote: why do you define the return type from the request as `any` just to later cast it to `Effort[]`? why not just `this.http.get("assets/data.json").then(({ data }) => ... )` – Thomas May 22 '21 at 12:33

2 Answers2

0

You forgot to initialize your effortsList and employeeList so they are both undefined, what means you cannot call arrays methods on them.

export class DataproviderService {
  effortsList: Effort[]
  employeeList: string[]
  constructor(private http: HttpClient) {
    this.effortsList = []
    this.employeeList = []
  }

  getData() {
    return this.http.get < any > ("assets/data.json")
      .toPromise()
      .then(res => < Effort[] > res.data)
      .then(data => {
        data.forEach(employee => this.employeeList.push(employee["Employee"]))
        return this.effortsList = data.slice();
      })
  }
}

Additionally, this line is not a good approach:

data.forEach(employee => this.employeeList.push(employee["Employee"]))`

I suggest you to change it to this:

this.employeeList = data.map(employee => employee["Employee"])

This way you will be sure that your will never push same items from data to your employeeList (e.g. If you will call getData twice).

ulou
  • 5,542
  • 5
  • 37
  • 47
0

Your employeeList is not initialized. You only declared it, but didn't assign a value.

You can also simplify your code when you just do

getData(){
  return this.http.get<any>("assets/data.json").toPromise()
    .then(res => { 
      const data = <Effort[]>res.data;
      this.employeeList = data.map(e => e.Employee);
      return this.effortsList = data.slice();
     })
  }
}

And also take notice, that toPromise is being deprecated and will be removed soon. https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated

derpirscher
  • 14,418
  • 3
  • 18
  • 35