Inject a service in a model class Angular

10,189

Solution 1

What you are trying to do is reasonable, the way you are trying to do it is considered a bad practice (big flame war back in the day so not going to get into that)

One of the better ways to do something like that is use Factories to construct your objects.

So your code would look like:

// Component needing model
@Component(...)
class SomeComponent {
    constructor(sellFactory: SellFactoryService){
        const sell = sellFactory.getNewSell();
        console.log(sell.userId)

}

/// Sell factory
@Injectable()
class SellFactoryService {
    constructor(private _userService: UserService){ 
    }

    getNewSell(){
       const sell = new Sell();
       sell.userId = this._userService.id;
       return sell;
    }
}

// Your sell class remains dumb (btw Sale would be a much better name for a model)
export class Sell {
  userId: string;
  price: number;
}

This way everything remains decoupled and testable.

Solution 2

You shouldn't inject service there. Sell class will be just too 'smart' then. I think there are two proper ways to do it:

Inject UserService into SomeComponent (just add it to constructor), and then do

let sell = new Sell(this.userService.id);

Second way is to create another SellService, which will have UserService injected. It will have method createNewSell(), which will be the same as code snippet above.

Share:
10,189
Pedro Arantes
Author by

Pedro Arantes

There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. — C.A.R. Hoare

Updated on June 14, 2022

Comments

  • Pedro Arantes
    Pedro Arantes almost 2 years

    Suppose I have a service which contains info about the logged user in my Angular application. I have a model called Sell that contains a field which is the user id who instantiates some Sell object. Is there a way to inject (I don't know if "inject" is the best word here) the user service inside the model in such way when the constructor is called, Sell takes the user id automatically and assign it to object?

    Example:

    user.service.ts

    ...
    @Injectable()
    export class UserService {
      private _id: string = 'some_id';
    
      get id(): string {
        return this._id;
      }    
    }
    

    sell.model.ts

    export class Sell {
      userId: string;
      price: number;
      ...
    
      constructor() {
        // some way to have userService here
        this.userId = this.userService.id;
      }
    }
    

    some.component.ts

    import { Component } from '@angular/core';
    import { Sell } from '../models/sell.model';
    
    @Component({
      ...
    })
    export class SomeComponent {
    
      newSell() {
        let sell = new Sell();
        // with this line, I'd want that the model itself assign user id
        // to its object.
        console.log(sell.userId) // some_id
      }
    }