Should services in Angular 2 hold the data manipulation logic or the components?

2.3k views Asked by At

This could be tagged opinion based. But I am looking for standard/best-practise. I am building an Angular 2 application and I have to manipulate the data from the API before I show it in the template. For example, if my service looks like:

getData(id: number): Observable<Data> {
    return this.http
      .get(this.url + '/' + id)
      .map((res) => {
        return res.json().data;
       });
  }

  prepareData(data) {
    // manipulate and return the data
  }

And on my component, I could call the service like this:

getData(id: number): void {
    this.dataService.getData(id)
      .subscribe((data: Data) => {
        this.showData = this.dataService.prepareData(data)
      };
  }

But is this the standard approach? Or should the prepareData function be included in the component instead?

Another way to phrase it is, should the service be heavy when compared to components or should it be light and only act as an interface to get the data?

3

There are 3 answers

1
salezica On BEST ANSWER

Simple, generic transformations everyone will need (such as res => res.json().data) should go in the service.

View-specific transformations that depend on presentation logic (such as data => data.user.firstName + ' ' + data.user.lastName) should go in your components.

The service should be able to provide data without knowing what will be rendered. The Component should be able to render data without knowing where it came from.

2
G. Stoynev On

Think of your angular application from the n-layer architecture perspective. Respect the DRY principle and and least some of the SOLID points - in this case the S in your services. Think of "Components" as view-presenter pairs (where the model is somewhere else), rather than ASP.NET's webForms (markup coupled with code behind).

There are two basic possibilities that will influence details of your design - is your service server endpoint aware of your view models or not. Some teams take the approach, where little transformation is needed in your angular application, because the server-side models are very close to angular view models. In those cases, anything that is not view-specific is okay to be in your service, with the view-specific transformations being okay in the component.

On the other hand, if you need to map a more generic service/server response into your angular view model, you don't want to do this in the service. Nor you want to do this in the component if there is the possibility to reuse this model (think of it as business class, not just DTO) in other views. Since mapping may involve business rules, it's better to isolate a dedicated model and mapper layer in your angular application and keep services and components DRY and "S". Creating a separate model/business layer is also good, because it may actually help you easily replace UI framework later.

0
Devansh On

You can manipulate and return the data in getData(). You can write your code as following-

getData(id: number): Observable<Data> {
    return this.http
      .get(this.url + '/' + id)
      .map((res) => {
          let data=  res.json().data;
          return this.prepareData(data);
       });
  }

  prepareData(data) {
    // manipulate and return the data
  }

I hope this will help you if you have specific condition you can describe in brief and i'll help you.