DEV Community

loading...
Cover image for Looking for Angular Architecture Advise

Looking for Angular Architecture Advise

thorstenhirsch profile image Thorsten Hirsch ・2 min read

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.

resolve observables in the child components

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:

resolve observables in the parent component

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() 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?

Please share your recommendations!

Attributions for the cover image go to jannoon028 from www.freepik.com.

Discussion

pic
Editor guide
Collapse
paulmojicatech profile image
paulmojicatech

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.

Collapse
ayhanyildiz profile image
Ayhan Yildiz

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?

  • You can initialize Subjects as Class property. Constructor mostly used for injection in angular.

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?

  • If you subscribe in Service it is bit difficult to unsubscribe. Leave subscribing/unsubscribing to Components.

Is it a bad pattern to have an Observable foo$ together with its resolved data foo in the same class?

  • It will be if you don't update your cached data. You can have cached data when app loads and shared that and never bother with subscription. There are cases you can use it. Observables are not only way to share data.
Collapse
jwp profile image
John Peters

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.