In certain rare scenarios, you should create an instance of a class and call its methods directly within a Blade view, rather than from a controller. For these cases, Laravel provides the convenient @inject directive:
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
Top comments (15)
Thanks for the motivation!
You also explained the example in a very clear way. I know it might not be the best solution, but I mentioned in the comment that I just wanted to highlight this directive since itβs not very common.
@xwero Yeah, I know itβs rare and a bit trickyβbut I clearly mentioned itβs a rare scenario. Personally, I havenβt faced it myself, but it could happen to anyone for any reason!
If you think it is tricky and you can't think of a use case, why would you promote the feature with a post?
Wouldn't it be better you show people Laravel features that helped you to come to a solution?
Just highlighting a useful feature I came across β it might help fellow developers. If you know a practical use case, drop it in the comments to benefit others.
How is it useful when you yourself can't find a use case, other than copying the Laravel documentation.
And even for the example from the Laravel documentation there is a better way of doing it.
I think they got the idea from ASP.Net, but there it is useful because the template files are classes disguised as html files.
I asked AI for an example and it provided a better use case than the Laravel documentation.
But even this could be solved better, with a custom directive
I don't see any reason to use this functionality, other than to get a WTF out of someone who is reviewing the code.
Very cool, the @inject thing saves me from passing endless vars. Super handy
Thanks!
Could you give an example?
I looks like a cool trick, but adding an dependency to your template is going to to make it harder to test.
The better way is to add the data you need for the template using the data argument when calling the the view in the controller.
It is also easier to read in the template
Monthly revenue: {{ $monthlyRevenue }}
.I noticed you presented a difficult example, especially since it's not drawn from real-life scenarios. I was simply highlighting a directive that might be unfamiliar to many developers, but it could still help others with similar challenges.
Why is the example difficult?
Having a model field that contains markdown is not out of the realm of possibilities. A real world scenario is when you don't want editors using an WYSIWYG editor, but they need to be able to add some markup like titles, bold text and links. Markdown if perfect for that.
If you are referring to adding the data when calling the view, how is that solution not real world?
I have nothing against highlighting functionality you think should be used more.
The problem I have is that this functionality exposes too much backend logic in the templates. Why would the template be aware of a service and knows which method to call? This should be hidden from the templates.
You can always achieve it, it is a developers choice not to do it.
The only tight coupling is between the router and the controller. All other coupling is loose because it is configurable or swapable.
I agree, the choices can be made due to time constraints or lack of knowledge.
But in the case of this functionality I think the knowledge will create more bad code than good.
I'm thinking about the goto operator in PHP. It is there but it will never be the best solution for a problem.
When the view is build dynamically, I would think that same mechanism can be used to get the data for a partial?
I have been trying to find a a legitimate case where @inject is the only solution. And for each case I found, there was a better solution.
I really want to be proven wrong that there is a case where @inject is the only solution.
This has nothing to do with my objections of the functionality. My objections have to do with tight coupling.