0

Working with Angular 2. I have a component and service. In the component I make request to get a list of companies. It then calls the Service to get the companies through an API. On response the companies are stored in a service variable called companies. In addition an observable is announced called announceCompanyData(). The component listens to the event and the request the service for the data and refreshes the UI.

I feel this a complicated way to handle HTTP response. Is there are simpler way to do this in Angular 2? Here is my code is below:

Service

@Injectable()
export class CompanyCommService {
  private companyDataAnnouncedSource = new Subject();
  companyDataAnnouncedSource$ = this.companyDataAnnouncedSource.asObservable();
  company: any;
  url: string = APIDOMAIN;
  constructor(public authHttp: AuthHttp, public http: Http) { }  
  announceCompanyData() {
    this.companyDataAnnouncedSource.next();
  }
  getData(i) {
    if (i==='companies') {
      return this.companies;
    }
  }
  getCompanies() {
    console.log('JWT');
    let headers = new Headers();
    let data = null;
    let id = 'fc65c467-336c-4271-85c3-278e419ac39d';
    var token = localStorage.getItem('id_token');
    console.log(token);
    headers.append('Authorization', 'Bearer ' + token); 
    this.http.get(this.url+ '/companies', {headers: headers})
    .map(res => res.json())
    .subscribe(
      data => { 
        this.companies = data;
        this.announceCompanyData();  
      },
      err => {
        console.log(err);
      },
      () => console.log('Request Complete')
    );
  }  
}

Component

@Component({
  selector: 'app-company-directory',
  templateUrl: './company-directory.component.html',
  styleUrls: ['./company-directory.component.css']
})
export class CompanyDirectoryComponent implements OnInit {
  companies: any = null; 
  subscription: Subscription;

  constructor(private navCommService: NavCommService,private companyCommService: CompanyCommService) { 
    this.subscription = companyCommService.companyDataAnnouncedSource$.subscribe(
      status => {
      this.companies = this.companyCommService.getData('companies');
      console.log('New Companies Data',this.companies); 
    })   
  }
  ngOnInit() {

  }
  requestData(): void {
    this.companyCommService.getCompanies();
  }
}
1

1 Answer 1

1

Instead of announcing everytime to all the components subscribing to the observable you could just declare a method in service of type observable and subscribe to this method in the component so whenever you call the getCompanies method after it has completed the request it will return the data to component

In Service

getCompanies() (): Observable<Companies[]> { 
     return this.http.get(this.heroesUrl).map(this.extractData)
}

private extractData(res: Response) {
  if(res.status < 200 || res.status >= 300) {
    throw new Error('Bad response status ' + res.status);
   }

  let body = res.json();
  /* here you can save body in any global variable*/
  return body.data || {};
}

In the Component

ngOnInit() {
   this.companyCommService.getCompanies( companies => this.companies = companies , error => this.errorMessage = <any>error);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the response. This looks alot simpler. If I want to store companies within a service variable as well send it to component what would be the best way?
here this.extractData is a function (i have added this in answer) you can use this to store the value.
Hi Gave it a go but it gives an error on the component side. Excluding the getHeroes() typo I get an error supplied parameters do not match any signature call target
there is one more typo error replace getCompanies() () to ``getCompanies()`

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.