About Injecting a service in model


#1

Recently myself and a friend of mine had discussion about injecting a service inside a model. We knew that model are just used to represent and store data but my friend was just curious to know what’s wrong and downside of injecting a service inside a model. His argument is if service is injected to a model we can use that service to retrieve data?

Could some one please explain briefly is it a good practice to use a service in a model?


#2

If team members are looking where the data is retrieved they would expect that on the route or adapter. So unless the app is maintained by one developer I would not think this is a good practice.


Proper way to define data that comes back as a query
#3

Thanks for your reply. yes we are a big team so this would lead to confusion on the approach followed.


#4

@indvinoth I’d also add that on a more conceptual level it’s breaking the separation of concerns and could cause problems down the road. Essentially it’s a bad design compromise. The model is just supposed to define how your data should be represented. So it’s “concern” is just saying "here is a collection of attributes and their types, and it is named ". You can have computed properties on a model which can transform the data a little bit or format it differently but in generally your model should just be a blueprint for some data. That means a model should never do data fetching or rendering or other things that are outside its limited realm of responsibility. A model should never be aware of the global application state, or really any state outside of itself, and a service usually represents some kind of global app state.

So you could argue that because you can do something, why not do it? Or perhaps that since everything is just a javascript object it’s not that weird. But I would say that the conceptual ideas like models, controllers, views, routes, etc. exist for a reason and that is to keep your code organized and well designed. Violating these design best practice can lead to some pretty bad problems later on. I’m not one to be too dogmatic about any one design pattern or way of doing things, but sticking to convention and best practice as much as possible can make your life a lot easier.


#5

Unfortunately sometimes you have models that have computed properties and a common service is feature-flagging. Sometimes the properties that you compute on a model is based on what features you have enabled in the application.

To have to rip out computed-properties from a model simply because you now depend on feature-flag information seems quite silly.


#6

The argument above is to not load data in models, not to not ever inject any service into models. The title “About injecting a service in model” is misleading but if you read it carefully.

I think your use case, injecting a feature flagging service into models, is a totally valid one.


#7

I found this thread when trying to implement a client-side computed attribute that I would consider to be part of the model. For instance, what if I had a Customer for whom an attribute was “number of movie rentals in the past 6 months.” The API does not provide this attribute. I have to query the API for Rentals that meet these criteria and count them. Further, what if this number was a shown in a badge next to the user’s avatar all over the application - this makes it really messy to constantly include it everywhere in all the routes does it not? Actually, the Customer’s name could caption the avatar, but that’s easy because their name is a attribute … just like this computed attribute.

What’s proper design for this? Am I really supposed to create a “recentRentals” service I inject in the avatar component? I’m all for separation of concerns, but this ventures into incomprehensibly abstract to me. I would much rather just define a property on a Customer called “recentRentals” on the model and use an injected Store to query the API.