Lesson Description
The "Cart Services Q&A" Lesson is part of the full, Intermediate Angular: Signals & Dependency Injection course featured in this preview video. Here's what you'd learn in this lesson:
Alex uses the Angular DevTools to visualize injected services and the injector tree, showing the structure and providers in the app. He recommends designing services with single responsibility, typically stateless and focused on specific APIs, while managing state separately.
Transcript from the "Cart Services Q&A" Lesson
[00:00:00]
>> Alex Okrushko: I'm going to show you a few more things now. But if you have any questions, prepare the questions as well. I'm going to show you some of the things, and this is related to, again, our Angular dev tools. All right, so I want to show you here, so see this injected services, right? So we can also see where things are injected, right? And again, this is app root, a header, that's where the cart service is injected.
[00:00:35]
Again, the other cool things you can see, and we can also see the injector tree. Again, we've seen it a little bit already, but we can see that at root, we have like 87 different providers, including if you are our injection tokens. Including if your injection tokens. Let me see if I can find this. I URL. There you go. And you can see, yeah, it's using the use value, so Angular, it's pretty powerful in our hierarchy here, and there's no providers other than we have in the root.
[00:01:21]
We have more during advanced Angular, but that is roughly what we have here. Ability to see specific injectors and specific components are also really, really awesome, so we can see inputs and services that are injected. As a general rule, if you're building out kind of a single responsibility kind of model application, you know, that's not clogged up with behavioral subject calls, the idea is that you would inject your signal, you know, to call into a particular service that has single responsibility like cart, or whatever its main job is, you know, to keep separation, that's right.
[00:02:14]
So right now, we do have separation. Typically, the way I structure, and we're going to probably talk more about it in the advanced Angular at the end, but generally speaking, just to go a little bit ahead. Whenever I create services, I typically try to have stateless services that are talking to specific API, so my cart service talks to tickets only, right, in this case, my event service talks to events only.
[00:02:49]
I typically try to have them stateless. I try to keep state managed separately. Again, this approach works and many people would be like, I don't want any third party dependencies. I really like my service with the subject approach. Again, it works. There's some drawbacks, you can't really control some of the race conditions. It's just some drawbacks, it's just something to be aware of, and sometimes it's fine, sometimes it's not fine.
[00:03:20]
You can, for example, work even this one around. For example, you can add the loading state for that specific API call and basically listen for that state in the buy button and disable the buy button altogether. Boom, you're kind of avoiding race conditions, but not letting them through at the button level. The problem is sometimes these things are missed, and it's hard to see that there is a race condition.
[00:03:54]
But I typically have services that are responsible for DTOs, data transfer objects, like events, basically are domain objects. I'll have them on singleton level, they'll probably could be used anywhere, and they don't really care how they're consumed. That's why even right now, we had a, I remember that when we delete the ticket, the reload of the resource was deferred to the component.
[00:04:20]
It wasn't part of the service. The reason for that, the service is like, hey, do I want to reload all the things, the GTP resources or not, like, it's basically for the component to take care about it, right? So, it purely deals with the backend and does not really know how the data is consumed out of it by components. So, then there are other layers, sometimes very useful, that we're going to talk about in the advanced Angular, and I think I'll try to make sure that the entire picture comes together at that point.
[00:05:04]
Someone was asking if having a computed signal as read only is redundant. And no, so read only, it's a good question actually, I like it. So read only means we cannot assign this value, so if we have this, not a read only, some, my, let's go to my, for example, my header. And then my header injects the service, right, so I'll just do this service. Service just to be brief, and then say my constructor, I'm like, you know what, this service, this discounts, screw this, you're now this.
[00:05:56]
So now it says strings on a signal the signal, but OK, I'll, let's really make it happen. Signal, signal, signal of, signal, OK, that's fine, let me just report that, now it's fine, not assembled to writable signal, OK, so basically we need to do, what can we do this as, as read only. That should work. Signal string number, OK, what's the number? All right, here you go.
[00:06:32]
I just screwed it up for all the other components that might be listening for this, so this is where read only is good, so I cannot reassign the reference for this value. It doesn't mean that the count never changes, it means that this property cannot be reassigned to anything else. The same thing like for private, again, it's not even accessible, but yeah, read only is, it never can be reassigned, if I do it this way now.
[00:07:05]
Now, if I go to my editors like, hey, you know what, you cannot assign count because it's a read only property. That's a good question, so we're not really assigning the value of the signal, we're not, it's about the reference to certain things.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops