OldGrey
OldGrey

Reputation: 83

Angular observable problems

I've been trying to get observable's working for a bit now, but i keep failing.

At this moment, my code is starting to look more like a battlefield then the order it normally used to be.

I keep getting the "ERROR TypeError: Cannot read property 'map' of undefined."

I am trying to import json data (which works), then filter out the members who are "Active" (which works), sort them alphabetically (which does not work) and get a unique list of everything that is in "team" column (which doesn't work).

The service looks as follows:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
//import 'rxjs/add/operator/catch';
//import 'rxjs/add/operator/map';
import { catchError, map, tap } from 'rxjs/operators';

import { Member } from '../class/member';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable()
export class UserinfoService
{

    //constructor
    constructor(private http: HttpClient)
    {

    }

    //methods or services

    getMembers(): Observable<Member[]>
    {
    return this.http.get<Member[]>('http://datalocation.com/JsonData/api/teammembers');
    }
}

the component:

import { Component, OnInit, Injectable } from '@angular/core';
import { UserinfoService } from '../services/userinfo.service';
import { Member } from '../class/member';
import { MatDialog } from '@angular/material';
import { MemberdialogComponent } from '../memberdialog/memberdialog.component';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';

// import 'rxjs/Rx'; // adds ALL RxJS statics & operators to Observable


// Statics
import 'rxjs/add/observable/throw';

// Operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';



@Component({
  selector: 'app-teammembers',
  templateUrl: './teammembers.component.html',
  styleUrls: ['./teammembers.component.css']
})
export class TeammembersComponent implements OnInit
{

  //props
  teamMembers: any[];
  searchQuery: any = "";
  searchResults: any[] = this.teamMembers;
  teams: any[];
  selectedTeam: any;

  //constructor
  constructor(private userinfoService: UserinfoService, public dialog: MatDialog)
  {
    //getData
    userinfoService.getMembers().subscribe(teamMembers => this.teamMembers = teamMembers
.filter(member => member.isActive)
.sort((a, b) => a.lastName.localeCompare(b.lastName)));


    //put all information in results
    this.searchResults = this.teamMembers;

    //getTeams
    this.teams = this.teamMembers
    .map(item => item.team)
    .filter((value, index, self) => self.indexOf(value) === index)
  }

Any help would be greatly appreciated. I got everything working when it was just a service, but the moment that i started with observables, it got all messed up.

Upvotes: 0

Views: 583

Answers (3)

ibenjelloun
ibenjelloun

Reputation: 7713

The code inside subscription is run asynchronously.

You are trying to do a this.teamsMembers.map before this.teamsMembers is set by the subscription.

You should put your this.teams = this.teamsMembers.map... code inside subscribe lambda function.

Upvotes: 3

CHAZTATS
CHAZTATS

Reputation: 114

You just need to move everything inside your subscribe.

Also not 100% on doing everything here in the constructor, I normally do this sort of thing in my ngOnInit but that's neither here nor there right now.

The other thing you can do is: teamMembers: any[] = new Array(); This will actually initialise your array properly so that it isn't undefined.

Upvotes: 1

Ankit Prajapati
Ankit Prajapati

Reputation: 2820

userinfoService.getMembers().subscribe(teamMembers => this.teamMembers = teamMembers .filter(member => member.isActive) .sort((a, b) => a.lastName.localeCompare(b.lastName)));

Heare you have already got the teamMembers array in component variable. so no need to required map in the later part. you can directly use the filter on the teamMembers array.

//getTeams
this.teams = this.teamMembers.filter((value, index, self) => self.indexOf(value) === index)

Upvotes: 1

Related Questions