Use an external Angular provider within withComputed or withMethod

Tomasz Ducin
InstructorTomasz Ducin
Share this video with your friends

Social Share Links

Send Tweet
Published 3 months ago
Updated 2 months ago

In this lesson, you’ll learn how to integrate external services with NGRX Signal Store with Angular’s inject API.

To make this work we'll be covering:

  • Angular's injection context, which is the scope within which Angular’s dependency injection (DI) mechanism is active and capable of providing dependencies.
  • How we inject the service in a default value to ensure that the injection happens properly within the injection context.

[00:00] Sooner or later, we will need to integrate our NGRX signal store with some other services that are external to our store. I have created an empty logger service, which has no methods yet. So let's create a log message, example method, which accepts one argument, which is basically anything. And we're simply [00:20] going to console log whatever the argument was just to have an example method that we would need to invoke whenever some code from the NGRX signal store is being executed. Now we don't want any consumers, for instance, components, to do the gluing between [00:40] the store and the service itself. We would like the store to be able to invoke the service directly. So what we can do is within the with computed and the with method methods. So what we can do is to extend the callback that is being passed to the with method and [00:59] add one more parameter to this callback. And in our case, this is going to be our logger. So let's say that this is basically the logger and using the new Angular inject API, we can simply import it from the Angular slash core and ask for the [01:19] instance of the logger service. Now our logger service is provided in the root injector, so we don't have to worry about the providers in this case. And this is all that we need. So let's take a look at one of the methods that is going to simply make use of this [01:38] injected service. So within the clear filters method that we have implemented previously, let's just call the logger dot log message and here clear. Start it, and let's print a similar message at the very end of the function. And that would be clear. Finished. Let's also [01:58] see this in practice. Let's see that it works. So here we've got the console up and running. And if we write something over here and we clear, we can clearly see that both messages has been displayed. Now there is one important thing to note about the usage of the inject function. The inject function has to be called [02:18] within what is called an Angular injection context. Injection context is we can think of it of a point in time in which Angular is capable of injecting all the providers that are available within the dependency injection mechanism. It means that if you are outside of the injection context, it's [02:38] basically too late to inject anything. And an example of a situation that is within the injection context is a constructor or a field initializer. And an example of a situation where we are outside of the injection context is inside a method. So whatever we would put here, this is going to [02:57] fail since this call is outside of the injection context. But, nevertheless, what is important is that this inject is going to be called within the injection context depending on when are we going to inject the store itself. So if this [03:17] is a field initializer, this is within the injection context. So this one, And again, this is not the with method itself, it's the callback that is passed into the with method. So the callback is also going to be executed at the same time when the store itself is injected. So we [03:37] are guaranteed that this is indeed within the injection context. Now why is that important? It's because this piece of code is pure Angular code, and NGRX itself has no support for this piece, what so ever. So NGRX is not responsible anyhow for injecting anything. So how [03:57] this works is because we are using or NGRX design is using a slight TypeScript trick, and that is if we provide a function that can support only 1 parameter and we, of course, pass 1 parameter, this is absolutely fine. However, if we pass a callback that is expecting more than [04:17] 1 parameter, but only 1 is supported, then TypeScript is going to yell at us saying that there is basically no signature that would match our call. However, things change if we provide a default parameter, which basically makes this parameter as a non required one. [04:37] Because it's okay to call this function with only one parameter. So if we basically call this whatever we want and provide the initial value, the default value of whatever it is. And in this case, this turns out to be a call to the dependency injection mechanism, which in turn [04:56] needs to be executed within the injection context. Everything works automatically, even though NGRX could have no support for this whatsoever, as mentioned before. And using the fact that we are combining the syntax and the type compatibility of TypeScript functions, we can apply the very same mechanism [05:16] also to the with computed, in this case. So here again, within the computed, we could also use the injected services. Now most often, you would need to use the injected services in order to run some side effects within your methods. You should not run your side effects [05:36] within the computed signals since computers are meant to be pure functions, pure calculations, and should not include side effects.

egghead
egghead
~ 21 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today