ngTemplateOutlet is WAY more useful than I realised

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 มิ.ย. 2024
  • My modern Angular course: angularstart.com/
    In this video, we explore a situation where *ngTemplateOutlet can turn an impossibly messy component into something beautiful. We will discuss the role of ng-template, how we can use *ngTemplateOutlet to display them, and why just using components and inputs isn't viable.
    Get weekly content and tips exclusive to my newsletter: mobirony.ck.page/4a331b9076
    Learn Angular with Ionic: ionicstart.com
    GOOD source code: github.com/joshuamorony/ng-te...
    BAD source code: github.com/joshuamorony/witho...
    Stephen Cooper: • ngTemplateOutlet: The ...
    0:00 Introduction
    0:45 What is ng-template?
    1:46 What is ngTemplateOutlet?
    4:05 API of the custom table
    6:21 Using ngTemplateOutlet
    10:06 Implementation without ngTemplateOutlet
    15:13 Conclusion
    #angular
    - More tutorials: eliteionic.com
    - Follow me on Twitter: / joshuamorony

ความคิดเห็น • 101

  • @JoshuaMorony
    @JoshuaMorony  11 หลายเดือนก่อน +1

    Join my mailing list for more exclusive content and access to the archive of my private tips of the week: mobirony.ck.page/4a331b9076

  • @AlainBoudard
    @AlainBoudard ปีที่แล้ว +25

    Yeah, I followed the same path from Twitter posts and went back to the basics to grasp this feature better.
    I ended up in the source code of PrimeNg - that I use in my actual job daily - and I love it !
    I'm glad to see that the Angular folks keep on sharing that kind of stuff so wee all grow !
    Cheers :)

    • @AlainBoudard
      @AlainBoudard ปีที่แล้ว

      I forgot to say that your video is impressive in details ! I had this one as reference : th-cam.com/video/2SnVxPeJdwE/w-d-xo.html

  • @TayambaMwanza
    @TayambaMwanza ปีที่แล้ว +50

    The sad thing is that there's hardly any documentation about it on official angular docs I.e examples etc

    • @Nate-gi7no
      @Nate-gi7no ปีที่แล้ว +7

      Yep. The angular docs are really lacking on the advanced features

    • @ImperiumLibertas
      @ImperiumLibertas ปีที่แล้ว +10

      ​@@Nate-gi7no which is a shame because it's the advanced features that makes Angular shine over other frameworks.

    • @TayambaMwanza
      @TayambaMwanza ปีที่แล้ว

      @Cristian Stefan why is it trash?

  • @cristiandegracianuero4854
    @cristiandegracianuero4854 ปีที่แล้ว

    Your channel is gold man, I'm going to share it with my job partners!

  • @AleksandarT10
    @AleksandarT10 ปีที่แล้ว +1

    Great video!
    Totally changed my perspective on ngTemplateOutlet !
    Usually all examples out there are just plain simple that really do not make sense to use.
    Keep up the good work and it would be great if u can make more such videos explaining "ambigious" topics

  • @TheTom265
    @TheTom265 ปีที่แล้ว

    Really well explained mate. Great stuff.

  • @bromptonhorsing8597
    @bromptonhorsing8597 ปีที่แล้ว

    Your video gave me an idea how I could refactoring messy table in our project. Thanks! Great Video

  • @maximilianvitzthum5591
    @maximilianvitzthum5591 ปีที่แล้ว

    Thanks for the videos, really helpful content. Please keep making those.

  • @ReymarMend
    @ReymarMend 3 หลายเดือนก่อน

    Wow, Amazing, I had no idea about this, a well deserved like!

  • @adodragicevic3786
    @adodragicevic3786 ปีที่แล้ว

    I love your videos on Angular! The best

  • @family-trails-and-tales
    @family-trails-and-tales ปีที่แล้ว

    Great explanation, thank you for sharing @Joshua.

  • @ico0z
    @ico0z ปีที่แล้ว

    A very very useful information provided and explained. Awesome work thanks for sharing.

  • @yaibanoutsukushii
    @yaibanoutsukushii ปีที่แล้ว

    this is amazing! I can't wait to try it out

  • @collinsk8754
    @collinsk8754 ปีที่แล้ว

    Your video definitely helped with this feature! Shukran! 😊😊

  • @kiritgupta
    @kiritgupta ปีที่แล้ว

    Thank you for this video, I’m going to share it with my coworkers. Our in house table component is a ‘component’ as per your example, and it takes this monster ‘columnConfig’ object. Our table does sorting, filtering, pagination and supports any number of action buttons as the last column. We do not use ngTemplateOutlet, I’m sure everyone will agree it’s better and maybe worth building a new table component that uses it.

  • @KrycekA
    @KrycekA ปีที่แล้ว +4

    Thanks for sharing a detailed explanation Josh! If I knew about this a few months earlier, my code would have looked a lot better as I ended up having a reusable component where I had to "configure" wether some parts of the template should be rendered or not.

  • @randomcoggles3805
    @randomcoggles3805 ปีที่แล้ว

    Good quality education. Thanks!

  • @Nabulio85
    @Nabulio85 11 หลายเดือนก่อน

    Thank you.
    Great content, great channel. ❤

  • @monfernape
    @monfernape ปีที่แล้ว +4

    This is black magic. So cool. I've used primeng table a lot lately and I always wondered how does table pass value to `let-row`

  • @chadbekmezian4806
    @chadbekmezian4806 ปีที่แล้ว

    Super helpful! Thank you!

  • @sroDrakso
    @sroDrakso ปีที่แล้ว

    Thank you! Keep going! awesome video!

  • @mersaCS
    @mersaCS ปีที่แล้ว +4

    You can even use this with service.
    Ex:
    In root router component, when you want specific layout to dynamic like button or even a dialog.
    Just create service and observable to listen and set.
    And inject the service from whatever children component with TemplatePortal and use it with viewchild decorator

  • @magmarrex5939
    @magmarrex5939 ปีที่แล้ว

    Very good material pls make more from Angular.
    I love this framework!

  • @octavian3033
    @octavian3033 ปีที่แล้ว

    Great video. Thanks a lot.

  • @mayanksati1842
    @mayanksati1842 ปีที่แล้ว

    Great explanation.

  • @muhamedkarajic
    @muhamedkarajic ปีที่แล้ว

    Useful video!

  • @igorproshchenko6280
    @igorproshchenko6280 ปีที่แล้ว

    Hey, what a great content you have!
    Subscribed

  • @khumozin
    @khumozin ปีที่แล้ว

    Nice video! 💯 I have implemented the second solution in one of my projects, but with less code.

  • @stonecoldcarebear
    @stonecoldcarebear ปีที่แล้ว

    Subscribed. Great video, thanks for sharing.

  • @p.s29
    @p.s29 ปีที่แล้ว +1

    Great video. I was just experimenting with ngTemplateOutlet on stackblitz yesterday...
    I did one extra thing and that is binding a function to the template passed in content projection.
    Not sure whether that is an optimized way or not but it worked except the type checking.

  • @MrEltoni12
    @MrEltoni12 ปีที่แล้ว

    As soon as the twitter message suggested a table i chuckled thinking that is the perfect way to showcase this feature.

  • @callimardisotope7963
    @callimardisotope7963 ปีที่แล้ว

    I love you, Thanks for this really instructive video 👍😁

  • @BillMoman
    @BillMoman ปีที่แล้ว

    Thank you - this is really helpful

  • @sant11h
    @sant11h ปีที่แล้ว +5

    Great video! I think I speak for all that features like this are not very well documented in the angular docs and we would appreciate more videos about advanced angular features. Thanks!

    • @FLevi-pi5vt
      @FLevi-pi5vt ปีที่แล้ว

      I did find that too, looking at most angular doc examples (if there were any examples) I was only left scratching my head. Maybe that's by design, there are many paid courses online.

  • @sabelogumede8951
    @sabelogumede8951 ปีที่แล้ว

    This will change my life, thanks Josh😅

  • @parsamh78
    @parsamh78 ปีที่แล้ว

    It really helps.
    thanks a lot

  • @Stevexupen
    @Stevexupen 3 หลายเดือนก่อน

    i learned about this when i was trying to reproduce react's render prop concept in angular

  • @g-luu
    @g-luu 11 หลายเดือนก่อน +1

    Great content as awlays.
    I'm interested in seeing how would customizing a specific table column would like. The current setup seems you need to redo all your your columns when you want to customize a single column like include an icon for column name.

  • @vitruvianeli
    @vitruvianeli ปีที่แล้ว

    I didn't just like the video; I also added it to the special list. Joshua, you are a fantastic content producer. Thanks.

  • @kaisteinkellner7331
    @kaisteinkellner7331 ปีที่แล้ว

    Great content thanks a lot !

  • @vivekpachouri4059
    @vivekpachouri4059 ปีที่แล้ว

    Great video and superb explanation. Please do a similar video for ngComponentOutlet?

  • @jordisarrato331
    @jordisarrato331 4 หลายเดือนก่อน

    amazing!

  • @CodingAbroad
    @CodingAbroad ปีที่แล้ว +2

    We can also use this to have a reactive form benefitting from the async pipe

  • @RoyerAdames
    @RoyerAdames ปีที่แล้ว

    Cool. Universal Studios Orlando uses this

  • @nChauhan91
    @nChauhan91 ปีที่แล้ว

    It’s like slots of a web component, nice

  • @hollow_ego
    @hollow_ego ปีที่แล้ว

    Really interesting video. I think I have used ngTemplateOutlet before, but can't quite remember the use case. I think it had something to do with using different inputs based on some condition.
    One feedback I would like to give: On small screens in the dark it is hard to read the actual. The contrast to the bright output on the right makes it hard on the eyes. I ended up blocking of half the screen with my hand.

  • @pyr0andrey
    @pyr0andrey 7 หลายเดือนก่อน

    @JoshuaMorony, thanks for the video. It was really helpful, but at the same time it reminded me of why I didn't like it when I've encountered it in the past. I am typing freak. Whenever I see the 'any' type I go bananas. Using this approach, the 'let-*' variables in the template will be of type 'any', which means no autocomplete/intellisense and can easily lead to errors that can be spotted only at runtime. I haven't had the chance of running into a similar scenario but here's one for ya: An ng-container with *ngFor that loops through some list of objects. Within this container, the type of the items is properly inferred, which is great. Let's say I need an ng-template that I can project into a child component of this container. Placing the ng-template inside the container works, we have typing, but at the same time we're creating a separate template instance for each item. Moving the ng-template outside the ng-container looses the typing. How can I go about that? Thanks again.
    Edit: I found your next video that tackles this exact issue (th-cam.com/video/dau7kQMdH4A/w-d-xo.html). Thanks!

  • @adamlawrence3651
    @adamlawrence3651 10 หลายเดือนก่อน

    This is a great example, basically allows you to write a reusable component, but give the flexibility that can't be given using normal components.
    I have seen ngtemplateoutput used a lot in the code base at work, and until seeing this I just wasn't sure if the benefit.
    it allows you to encapsulate display logic in a component, but allow the component using the re usable component to override this if needed.
    I still think it is over used on our current code base, but now have a better understanding when this technique should be used.

  • @tuntunpandit8367
    @tuntunpandit8367 ปีที่แล้ว

    Please make a video on Angular Life Cycle Hooks in detail with examples. Thanks

  • @prajwal5891
    @prajwal5891 ปีที่แล้ว

    Hey, what did you use to read the template string as html and not a string?

  • @praktycznewskazowki6733
    @praktycznewskazowki6733 ปีที่แล้ว

    great!

  • @kevintale2608
    @kevintale2608 ปีที่แล้ว +3

    Super cool! In short, I'd say ngTemplateOutlet is useful when the data sent to the dumb component should be rendered differently depending on the context of use.
    But I guess ng-content could also do the trick? I wonder if you've tried with ng-content as well.

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว +1

      There's a great explanation of why ng-content isn't powerful enough for the task in this case in the video I linked from Stephen Cooper, highly recommend checking it out

  • @crshbndcoot
    @crshbndcoot ปีที่แล้ว

    thanks

  • @xenon4602
    @xenon4602 ปีที่แล้ว

    Please make videos on Angular universal

  • @victorpetch8579
    @victorpetch8579 ปีที่แล้ว +1

    My use case on this was a CRUD page.
    I had a component doing a create operation, another one for editing, another one for reading..
    As it turns out, they all are 80% similar.
    Creating lots of components for similar stuff would have too much copied code.
    Instead, I created a bunch of templates and just switched them up based on the route of the page.
    If it's create, I'd use templates 1,2 and 3.
    If it's edit, I'd use 2, 3 and 5.. and so on.

    • @3pleFly
      @3pleFly ปีที่แล้ว

      The problem with this is readability. Are generic and DRY components good? Yes, essential? No.

  • @MahmoudTarek-pz1rl
    @MahmoudTarek-pz1rl 7 หลายเดือนก่อน

    I'm trying to build a custom table using angular material table, and providing a custom table row using ngTemplateOutlet is not working or Im just missing something..
    Any advice I'd be grateful.

  • @cburys
    @cburys ปีที่แล้ว

    Good information in here for sure. I still wrestle with why though. If you have to pass in a template for any variation, we lose reusability. IMO, if I have to write a template every time I use the component, why even use the component? Currently in our, as this video would call it, messy custom table implementation, we pass in an array of column definition objects, and then the data itself. The column definitions determine how the data is displayed, order of columns, and any non standard header behavior, etc. The component itself is a beast, but using it is a breeze.

  • @USONOFAV
    @USONOFAV 5 หลายเดือนก่อน

    kinda interesting what kind and how big your projects were that you can't find a use case for ngTemplateOutlet

  • @vvsg2
    @vvsg2 ปีที่แล้ว +1

    Wow, this is amazing, thank you. I didn't think you could do this in Angular!
    However, I think that this is still waaay too janky, and not well documented, compared to other frameworks (in React this is just basic stuff with render props)... It would be nice if Angular Dev Team will improve this pattern in the future!

    • @defenseman84
      @defenseman84 ปีที่แล้ว +1

      I would never do this in Angular do get that result. I think he’s just demoing a capability. The result here can be done much more cleanly. In fact, when using Angular Material, getting configurable tables is very easy and clean.

  • @yawarbhat2377
    @yawarbhat2377 ปีที่แล้ว

    Can we pass in a method in thr context ?

  • @timburstefan
    @timburstefan ปีที่แล้ว

    HI, can I ask a small question about displaying object data to the page when the values of the object have not yet come from the server, and the console throws undefined values until the data is fetched. This has been bothering me for some time and I don't know what solution to use, any advice would be amazing.
    I could initialize every single field of the object but I'm sure there is a better than this.

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว +1

      I will generally have a stream for any data that is loaded, then in the template use an *ngIf="myStream$ | async as data; else loadingTemplate" now the component will only render when data is available, otherwise it will display the loading template

    • @timburstefan
      @timburstefan ปีที่แล้ว

      @@JoshuaMorony That makes sense, thank you!

  • @LalindaDias
    @LalindaDias ปีที่แล้ว

    Hi @Joshua, Thanks for the video. I have a question regarding ng-template usage in template. Isn't it hard to do unit testing when we use ng-template for dynamically display content in template (component.html) ?

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว

      I haven't actually tried testing this code, but it doesn't strike me as something that would be a problem - is there something specific that you think would be challenging?

    • @LalindaDias
      @LalindaDias ปีที่แล้ว

      ​@@JoshuaMorony Sorry for the late response. I read an article recently in Medium that strongly suggests not putting any logic inside templates because it would be harder to unit test that logic.

  • @_rohit_s
    @_rohit_s ปีที่แล้ว

    I've a question
    A parent component and we pass children components by router-outlet , & if we want to pass value @Input I know we can use service here but I want to use @Input here

  • @monfernape
    @monfernape ปีที่แล้ว

    11:09 my eyes, my eyes.

  • @igorgaiduk5536
    @igorgaiduk5536 ปีที่แล้ว

    What will you do if you need to rerender data inside ng-template? Take a try and you will see the problem with ng-templates.
    Better to use a component for price and change showed value inside "ngOnChanges" life cycle hook.😉

  • @names-mars
    @names-mars ปีที่แล้ว

    I get why ngTemplateOutlet is easier, and I think there's no right and wrong way of doing this, it falls down to what you're trying to achieve. But in my opinion, both these methods you showed are messy, and I'm certainly not choosing the lesser evil xD. I think there should be a much much cleaner way of doing things. Currently working on making a widget library for an internal framework in this company I work for (they're vendors, and it's sad that they have to keep rebuilding things for every new requirements), high level widgets that are highly customizable based on the data model (well I guess the right term is a view model), and I definitely won't go for that first method you showed, I also already have 1 other approach that involves almost no complexity on the template layer. But currently, I'm just arranging ideas, haven't really settled on one and maybe I'm wrong, but I know what not to do at least. I want to keep the template layers as clean as possible so my UIUX team can focus on pure styling principles and not be bothered by angular's nuances.

    • @andrejohnson2079
      @andrejohnson2079 ปีที่แล้ว +1

      I'm curious as to this how you intend to achieve this? Apart from newer standalones, older use of CDK portals, or the ancient well-deserved frowned-upon misuse of innerHtml

  • @ur.kr.2814
    @ur.kr.2814 ปีที่แล้ว

    I've been using templates like this for a while. The only thing I don't like is the lack of typing for the Context object and its use in the let-contextprop attributes.

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว

      I have another video on strongly typing with context guard if you want to check it out: th-cam.com/video/dau7kQMdH4A/w-d-xo.html

    • @ur.kr.2814
      @ur.kr.2814 ปีที่แล้ว

      @@JoshuaMorony That's very useful, thank you! I will get a lot of use out of this

  • @mwdcodeninja
    @mwdcodeninja ปีที่แล้ว

    If you are already iterating over your dataset in a preprocessing step why not simply inject a button component into the results?
    You are combining business logic with display logic in your component example and that overcomplicates it. If you're using buttons, you're using a button component that knows how to handle clicks.
    But all that said, I appreciate the NG template explanation. I've struggled with it in the past but this helps the it all together.

  • @djglxxii
    @djglxxii ปีที่แล้ว

    Nice video. However, in the final "ugly" version, couldn't it have been a bit more flexible if you had used ng-content with named slots? Basically allow consumers to project content into the data table instead of using all those inputs.

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว

      I haven't explored pushing ng-content in this context to see if I could come up with a solution, but in the video I liked to by Stephen Cooper he explains the downfall of ng-content in this kind of scenario: th-cam.com/video/2SnVxPeJdwE/w-d-xo.html

  • @VinyciusOliveira
    @VinyciusOliveira ปีที่แล้ว

    I think that can also be done with ng-content...

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว +1

      Check out the vid I linked from Stephen Cooper for a good demo of why ng-content isn't quite powerful enough for this use case

  • @romarioputra3775
    @romarioputra3775 ปีที่แล้ว

    What is the use of context in thead?

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว

      I'm using that in the default headers template to get the keys from the data to use as default column names - not making use of it in the home component with these specific examples, but there could be a situation where you want to reference the actual data when supplying your header template.

    • @romarioputra3775
      @romarioputra3775 ปีที่แล้ว

      @@JoshuaMorony ahhh i dont even see that ☺. Thank you!

  • @thefather8362
    @thefather8362 ปีที่แล้ว

    Why not just create three separate components instead of one component that supports multiple use cases? Components are easy to create. My personal opinion is that components should be as simple as possible.

  • @bronzekoala9141
    @bronzekoala9141 5 หลายเดือนก่อน

    Funny that you have to explicitly tell it that a value is implicit 😂

  • @ChristopherNeurofunker
    @ChristopherNeurofunker ปีที่แล้ว

    forget that. just create different components 🤣

  • @JEsterCW
    @JEsterCW ปีที่แล้ว

    Angular is not useful at all, its a nightmare 😂

    • @AliciaGuitar
      @AliciaGuitar ปีที่แล้ว

      After you figure out the learning curve its fine. It forces good practices and thats a good thing even if it takes longer to master

    • @JoshuaMorony
      @JoshuaMorony  ปีที่แล้ว

      Why do you think Angular is not useful?

  • @spencereaston8292
    @spencereaston8292 ปีที่แล้ว

    My current SOP would have used viewContainerRef.createComponent for the child elements. This seems to have a lot less boilerplate then createComponent especially if the created components are not going to be consumed anywhere else.

  • @notarealhandle123
    @notarealhandle123 ปีที่แล้ว

    ngOutletTemplate is crap, because it is too limited: it does not support the essential create/destroy events, and no access to the component instance. The only good way is to implement it all yourself, which is what I did for my projects. If interested how I did it - reply to me with contact email, I will send you an example. It is possible that Angular v15 will get a proper ngOutletTemplate support finally.