Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 - reuse component with different services/providers

I am developing an app which has Restful API for backend and Angular2 for frontend.

I want to have two graphs in a view. Say, one graph is of employee-attendance and other is of product-sales. One API for each is available for fetching data from server.

How should I plan it?

Should I be having two components one employee-attendance and one product-sales, which in-turn will use their own services and fetch data and populate the component?

OR

Should I have only one component as 'graph'? In this case how to fetch data? Is there any mechanism / good-practices about services to achieve this?

Tried searching online by couldn't get any relevant guidelines.

Please help. Thank you.

like image 841
Yogi Avatar asked Sep 16 '16 12:09

Yogi


2 Answers

This is how I would of implemented it, a more of a OOP way.

Services:

export interface IGraphServices {
  getGraphData(): string;
}

@Injectable()
export class EmployeeAttendanceService implements IGraphServices {
  getGraphData(): string {
    return "Employee Attendance Data";
  }
}

@Injectable()
export class ProductSalesService implements IGraphServices {
  getGraphData(): string {
    return "Product Sales Data";
  }
}

Component:

@Component({
  selector: 'graph',
  template: '<div>Graph component</div>'
})
export class GraphComponent implements OnInit {
  @Input('service') service: number;

  constructor(@Inject('IGraphServices')private providerService: IGraphServices[]) {

  }

  ngOnInit(): void {
    console.log(this.providerService[this.service].getGraphData());
  }
}

In your NgModule providers:

providers: [
    {
      provide: 'IGraphServices', useClass: EmployeeAttendanceService, multi: true
    },
    {
      provide: 'IGraphServices', useClass: ProductSalesService, multi: true
    }
]

Usage:

<!-- EmployeeAttendanceService -->
<graph [service]="0"></graph>

<!-- ProductSalesService -->
<graph [service]="1"></graph>
like image 105
penleychan Avatar answered Sep 20 '22 10:09

penleychan


If it is a good idea to build two different or a single component is difficult to answer with the information you provided.

You can

  • inject the service in the parent and pass it to an input of the graph component.

  • inject both services into the graph component and pass a parameter to an input that tells the graph component which service to use

  • create one service that provides methods for employee-attendance and product-sales data and use an input in the graph component to tell it what method it should use.

  • use a parent component that has the provider registered that you want the graph component to use. When the graph component injects the service it gets the one provided by the parent.

@Component({
  input: 'my-graph',
  template: ' show the graph here '
})
class MyGraphComponent {
  @Input() data;
}
@Component({
  input: 'employee-attendance-graph',
  template: '<my-graph [data]="data"></my-graph>'
})
class EmployeeAttendanceGraph {
  constructor(private data:Service1) {}
}
@Component({
  input: 'product-sales-graph',
  template: '<my-graph [data]="data"></my-graph>'
})
class ProductSalesGraph {
  constructor(private data:Service2) {}
}

Then use it like

<employee-attendance-graph></employee-attendance-graph>
<product-sales-graph></product-sales-graph>
like image 23
Günter Zöchbauer Avatar answered Sep 22 '22 10:09

Günter Zöchbauer