taiga-family / ng-polymorpheus

Polymorpheus is a tiny library for polymorphic templates in Angular.

Home Page:https://stackblitz.com/edit/polymorpheus-demo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[FEATURE] Observables Support

BorisZubchenko opened this issue Β· comments

commented

πŸš€ Feature request

Is your feature request related to a problem?

I want to use this library with ngx-translate. I'd like to pass the translation which is an Observable<string> as PolymorpheusContent. I don't want to use ng-template for this since it's just a text. I also have to pass it in my component (to the Angular Materials Dialog's data):

this.dialog.open(MyDialogComponent, {
  data: {
    title: this.translateService.get('confirm.title')
  }
});

In the example above, the translateService#get returns an Observable<string>, but data's title has a type PolymorpheusContent. It is incompatible.

Describe the solution you'd like

It would be great if I could pass Observable<primitive> as the PolymorpheusContent.

I don't know if the observable should be exposed to the T, but it would be a great option since we don't know what do we have β€” an observable or not (in case of my feature request is implemented):

<!-- Should we use async? -->
<span>{{content}}</span>

But I came up with a workaround β€” a custom wrapper pipe that will async the value only if it's an observable:

transform<T>(value: T | Observable<T>): T {
  return value instanceof Observable ? this.asyncPipe.transform(value) : value;
}

Additional context

Maybe I've missed somewhere and it is available now. If so, please provide me an example since I did not find any solution in the demo.

Hi @BorisZubchenko. It's an interesting idea and it's reasonable to think that if polymorpheus is meant to consume all kinds of content it could handle Observables inside. On the other hand, I can hardly think of a case where you would create something that needs to have customizable appearance and you will not know if it is going to be Observable or plain content on the outside. So it seems like you could use async pipe when feeding content to polymorpheus. I wouldn't want to add a lot of logic to polymorpheus since the idea behind it is to use very little code and delegate all the work to Angular built-in functionality. I'll think about it some more but my initial reaction is it should be outside polymorpheus' scope.

Your workaround with custom pipe that optionally consumes Observables seems like a way to go. Closing this issue.

commented

@waterplea maybe it is, but I still cannot pass Observable<primitive> as a PolymorpheusContent:

It would be great if I could pass Observable as the PolymorpheusContent.

Yes, I explained my reasoning above. This could and should be handled outside Polymorpheus and the pipe you gave as an example is a decent solution.

commented

@waterplea, I understand your point. I was just replying to your comment:

Your workaround with custom pipe that optionally consumes Observables seems like a way to go.

The thing is that the pipe is useful only if we could pass observables since it takes value regardless of the context. In other words, without the feature I issued this pipe is useless.

Anyway, thank you for your time!

I don't understand. Here's an example I've made in Stackblitz. Isn't it what you need?
https://stackblitz.com/edit/angular-semi-async

commented

Your example works great with templates (and I don't even need a custom pipe for this).
The problem is that I have to pass the observable to the dialog:

this.dialog.open(MyDialogComponent, {
  data: {
    title: this.translateService.get('confirm.title') // returns Observable<string>
  }
});

Dialogs are dynamic components and I can pass data only in this way. I'd like to make title field of PolymorpheusContent type, but I cannot since it does not support observables. That's the problem.

Then your type should be Observable<PolymorpheusContent> | PolymorpheusContent and inside your dialog components you can use the pipe discussed above. It would be a requirement for dialog components to be able to handle both static and reactive content. I still think Polymorpheus itself should be as tiny and as logic-free as possible.

commented

Then your type should be Observable | PolymorpheusContent

Nice catch, I should definitely try it! Thanks!