After building one or two Angular applications it's time to ask if I'm doing things right. There might be a lot of beginner tutorials for Angular out there, but it's hard to find architectural best practices. My most urgent question is:
- How long to keep using data as an Observable? When can/should I "resolve" it to its actual data e.g. with the async pipe?
The answer might be "as long as possible", so I should always try to use an observable and only "resolve" it in the the html template where the data is finally being shown.
But I guess it's easier to use an observable as short as possible by resolving it in the parent component and providing the data as input for the child components like so:
I really don't know the answer. And here are some more questions I keep asking myself:
- Since I only want to fetch data from my http server once, but use it several times - where do I use ReplaySubjects? In the Services or in the Components?
- Should I instantiate Observables/Subjects when declaring their variables? Or should I instantiate in the constructor?
- When it comes to subscribe/unsubscribe I should probably use the
ngOnInit()
andngOnDestroy()
hooks, which are available in Components only... so I guess I should never subscribe/unsubscribe in my services, right? - Is it a bad pattern to have an Observable
foo$
together with its resolved datafoo
in the same class?
Please share your recommendations!
Attributions for the cover image go to jannoon028 from www.freepik.com.
Top comments (3)
Personally, I try to follow the smart component / dumb component pattern. With this, my parent component handles all the data to pass down to the child / dumb components. If a child component has some interaction that other siblings need to know about, I emit something from the child which will update the observable on the parent. I have been implementing this by injecting a service to the parent to that will contain a method to return an observable. In the service, I have a private BehaviorSubject so when the method is called to get the observable from the component, the method returns the behavior subject with .asObservable(). I also have an updateState method that will take a key and value as parameters. Here I use .getValue in the BehaviorSubject, update the key with the value, and cal .next() on the subject. In the template, I use async pipe to pass the data to the children. I have found it works pretty well for me and gives me a pattern to separate the business logic from the presentational component.
Since I only want to fetch data from my http server once, but use it several times - where do I use ReplaySubjects? In the Services or in the Components?
-When you fetch data from http it is not stream and it will be completed. If you want to share same fetched data with new subscribers you can use any Subject helpers to create new observable and share the data. These all needs to be done in service layer since they are built for the purpose of sharing data and creating instances. Please read angular dependency injection to grasp better.
Should I instantiate Observables/Subjects when declaring their variables? Or should I instantiate in the constructor?
When it comes to subscribe/unsubscribe I should probably use the ngOnInit() and ngOnDestroy() hooks, which are available in Components only... so I guess I should never subscribe/unsubscribe in my services, right?
Is it a bad pattern to have an Observable foo$ together with its resolved data foo in the same class?
Most of my observable usage is with http. The subscribe kicks off the action with the result going almost directly to the view. But there are other observable types and operators.