The CLEANEST authentication I've ever built with Angular

Поділитися
Вставка

КОМЕНТАРІ • 97

  • @JoshuaMorony
    @JoshuaMorony  8 місяців тому +8

    I have an Angular course launching soon - join the mailing list if you don't want to miss the launch discount: mobirony.ck.page/4a331b9076

    • @BalearicS0ul
      @BalearicS0ul 8 місяців тому +1

      Can you please tell us when can we expect it to arrive? And a bit more information on what will be included in the course? Thank you for all the great work!

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +3

      ​@@BalearicS0ul if you're on my mailing list I'll likely send some proper info out in a week or two - I expect to launch within a month. But it will be a full beginner to intermediate/advanced text based course covering everything from basics, state management/architecture, signals, RxJS, declarative code, multiple example applications, and more - basically a very big bloody course that teaches all the same sorts of things I talk about on this channel

    • @BalearicS0ul
      @BalearicS0ul 8 місяців тому

      @@JoshuaMorony That is great! I'm on your mailing list and also I've purchased the entire Elite Ionic course but in the meantime I've moved away from Ionic and focused only on Angular. Your upcoming course is exactly what I need to push me entirely towards TDD and declarative programming so I can't wait to dive right in. Good luck with the launch!

    • @kepdapace
      @kepdapace 8 місяців тому

      Signed up to the newsletter and looking forwards hear more about this course. You mentioned it is a text based course, would you consider making video tutorial walkthroughs to complement the course materials?

    • @ferlezcano
      @ferlezcano 8 місяців тому

      I can't wait to start that course! 💪

  • @timtim9o5
    @timtim9o5 8 місяців тому +1

    I think the usage of defer in this case makes perfect sense. Thanks for the content, you have many interesting innovations.

  • @joshuadc316
    @joshuadc316 8 місяців тому +1

    excellent as always, fellow josh!

  • @qwerty-or1yg
    @qwerty-or1yg 5 місяців тому +1

    Holy crap, the implementation, the explanation, as a noob I can say that it was really really clear and I thank you for that. Subscribed

  • @taner-saydam
    @taner-saydam 8 місяців тому

    Really interesting. I will look into this.

  • @deadlyecho
    @deadlyecho 8 місяців тому +1

    Very nice approach ❤, don't know why people think it's complex, it's pretty straightforward for me... maybe people not used to the new angular stuff yet

    • @TheAdamwest29
      @TheAdamwest29 5 місяців тому

      The declarative approach is a paradigm shift. Most programmers are doing things the "imperative" way due to functional programming concept.

  • @NejcPrincic
    @NejcPrincic 8 місяців тому +1

    Love it

  • @maxenn9936
    @maxenn9936 8 місяців тому

    I'm a big fan of demoing with real world examples 🔥love it 🙌
    Only thing is, I think people may get confused on your use with signal effect. It was mentioned while inside one component when there's a signal change another component would react to the signal. Do you think that could make things a little murky if you need to start considering service/components life cycles relative to one another🤔 None the less this is innovation right here, keep it up!

  • @floriandesmortreux4998
    @floriandesmortreux4998 8 місяців тому +7

    For me you are clearly making the kind of code you were against when I first watched you on the declative approach. You've stated multiple times through your videos that declative is when everything is in the declaration but your are now using computed values all over the place. You also have all signal being recomputed everytime a state changes and now a race condition in your code that your are proudly solving by using a timeout. This is crazy, your approach was better before, at least in my opinion

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +3

      Computed values are declarative, you can see exactly how they are calculated in their declaration just as you can with observables and they can not be imperatively changed anywhere. The non declarative parts of this process are where Subjects are nexted and the state signal is being updated. You are right that this is less reactive/declarative that what I have typically done before - having this reducer step where a signal is updated is inherently imperative versus having the data stay in the stream until it reaches the template or wherever it is going. The data is in a reactive/declarative flow again after the point it is set in the signal though. This is an intentional trade off - I think it reduces a great deal of complexity and doesn't lose much of the benefits of more "fully" declarative code (and no code in Angular is "fully" declarative anyway, so we are already making concessions somewhere).
      And the problem that I am using defer for would exist either way - I don't particularly like it either but it's also the nicest way I've seen of dealing with the issue.

  • @BrotherNifty
    @BrotherNifty 8 місяців тому

    using an observable stream to update a signal which triggers an effect is an interesting pattern which certainly reduces the requirement to maintain auth state in a browser or server cookie and to explicitly acquire it for every request

    •  4 дні тому

      Woah.. You still maintain auth state. You will still have to use tokens for API communication, this is not a proper authentication implementation but a demo of a concept.
      You still need tokens to make it possible for the back-end system to verify your authentication and authorization, you still need a way to say "this is me, and only me is me".
      This doesn't change anything about the requirements of auth systems. It only changes the way you can handle it front-end.
      And most of this was already possible without signals.
      The only thing now is that you use your computed value inside your http-interceptor, instead of piping a behaviourSubject or subscribing to it.
      You can technically do this with Signals only, but using the power of RXjs piping some observables with replay, restart, etc effects allows you to have more say in *when* your "effects" go off.

  • @TheAdamwest29
    @TheAdamwest29 5 місяців тому

    Thanks for the nice tutorial. I am sure it was a bunch of work to set up. I really like the declarative approach. I think some fine tuning of the nomenclature (i.e. "pending" is really more like 'ready', and 'authenticating' or 'creating' could be 'working' where the component itself provides the context to the question What is being 'worked' on?).

  • @additionaddict5524
    @additionaddict5524 8 місяців тому +1

    Nice diagram. I like the fact the arrows don't cross

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      Are you Andrew from twitter? lol

  • @TravisSomaroo
    @TravisSomaroo 7 місяців тому

    Great stuff josh, what is the theme you are using for your IDE?

  • @kylerjohnson988
    @kylerjohnson988 8 місяців тому +9

    I get why you feel that this is a bit of an abuse for defer, but logically I agree that this is a good use case for it. Since it was announced, it felt like it was a good use case to slightly delay pieces of the UI while state “settles”. While this could always be achieved with RxJS, this definitely feels like a cleaner, simpler approach.

    •  4 дні тому

      how though? Why not use a resolver? That also ensures the data is loaded before showing the component and it's not a hack like sleep(10).

    • @kylerjohnson988
      @kylerjohnson988 4 дні тому

      Defer gives greater flexibility. Resolvers keep the page blank until data loads making it feel clunky and slow. Using defer in the template would allow you to use the placeholder keyword to show something in the meantime. No blank page

  • @infodusha
    @infodusha 8 місяців тому +1

    The downside of the defer i see here is the thing that you have to use magic numbers. You newer know how long it takes angular to render the page, so assuming it as 50 ms or 200 ms (as it is in the tweet) is kinda a hardcode people normally would like to avoid.

  • @iliaboico4397
    @iliaboico4397 5 місяців тому +2

    Can somebody help me doing this with JWT, what should be instead of with state to change user stream?

  • @ilyatelefus3647
    @ilyatelefus3647 8 місяців тому +1

    @JoshuaMorony maybe you could use @placeholder, @loading blocks alongside with @defer to achieve the same result.

    • @reidyoung298
      @reidyoung298 7 місяців тому

      Isn't this issue typically handled by a specific ng-template for loading state?

  • @jlbz031
    @jlbz031 8 місяців тому +4

    I think that NgRx Signal Store would be good in this case. Are you planning to do a video about it when it'll be released and implement it with a scenario similar to this one ?

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +4

      Part of the reason for going with a vanilla/no library approach is because I am using this app in my Angular course for teaching (I like the idea of focusing on the underlying concepts). But I will also generally avoid libraries unless it provides a significant benefit (mostly because I like getting into problems with peer dependencies as versions change). I've seen some cool things happening in libraries with signals, but nothing yet that makes me want to use them by default - however, I have not yet checked out Signal Store, so it will be interesting to see how it compares to this sort of "default" approach and I probably will end up doing a video on it.

    • @viralmoney8619
      @viralmoney8619 8 місяців тому

      ​@@JoshuaMoronysir please we need separate playlist from ngrx and signal app 🎉

    • @schankam
      @schankam 8 місяців тому +1

      Ngrx Signal is so good tbh

  • @user-jy3cd1qi9q
    @user-jy3cd1qi9q 2 місяці тому

    I don't really get how to watch user$ = authState(...) when using another backend different from Firebase. In Firebase, what is the advantage of using authState? Why not setting the Angular state by subscribing to the login, logout, etc. methods response?

  • @filipefreire6517
    @filipefreire6517 8 місяців тому

    Been away from Angular since v10. Any specific videos of yours to catch up on what's new, especially since v16?

    • @reidyoung298
      @reidyoung298 7 місяців тому

      Typed forms, Signals, defer, Material updates and changes, standalone components, defer, new template condition syntax... I'm sure there are a few more

  • @deatho0ne587
    @deatho0ne587 8 місяців тому +1

    In some ways much nicer than imparitive, but it is missing a few key elements I am sort of mentioning below.
    Would it be easy to timeout a user if they have not done anything during the session for some time? This should be easish to login/reauth, would just need to think about it more.
    There is also a question in SSO realms, but will leave it do to I do not want to explain.

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      Haven't thought about a no actions timeout, but my first thought is that the best solution would probably be to create an abstraction around triggering actions (vs just nexting individual subjects) so that you can more easily react to *any* action being triggered if you need. Maybe there's easier ways though - just use the IntersectionObserver API or something to react to screen movement? I've never implemented one of these things so not really sure what the norm is

    • @deatho0ne587
      @deatho0ne587 8 місяців тому

      We use either a timeout that is set-up or an expire time of the token.

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      ​@@deatho0ne587 that should be pretty easy then - I would set up a new source that will emit whenever the timeout should occur, and then you can also have the timer in that stream reset via some other source that can be nexted (then if the condition for that was action being triggered you might to set up an abstraction there, but using something like the Intersection Observer to detect movement seems like an easier option to me)

  •  8 місяців тому +1

    Bro, I love your content where can I find the source code?
    I'm trying to learn TDD in angular do you know a good content that I could use?

    • @Dev_UI
      @Dev_UI 8 місяців тому

      description

    •  8 місяців тому +1

      @@Dev_UI ploat twist it is not

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      Yeah there is a link in the description for the source code and I've got a few recent videos on TDD in Angular if you haven't seen those already

  • @ErwinFRANCE
    @ErwinFRANCE 7 місяців тому

    Sorry if my question is a nooby one but here it is : As newcomer in Angular, I tried to find the best practices of 2023 to start working with it. I watched all of your previous videos and came with the conclusion that I need to understand concepts of RxJs, NgRX and signals. But with this new video, I don’t really see where I can put the NgRX pattern in it. If I understood this video you are using signals for the state management which is also a dedicated task of the NgRX pattern. Do we still need to implement NgRX ? Could you clarify this so that I can apply better code architecture and methodology in my future developments ? Thanks.

    • @ErwinFRANCE
      @ErwinFRANCE 7 місяців тому

      Edit : I should have keep track of all ur recent videos. You explain in many of them that you updated your working method and try to get rid off third party framework for state management. So it answers my questions. But I could still ask if this is possible to combine RxJs + Signals + NgRX and where NgRX would go in this equation ? 😅

    • @JoshuaMorony
      @JoshuaMorony  7 місяців тому +2

      @@ErwinFRANCE so you don't *need* to use NgRx (although you might want to) and personally I haven't used NgRx for a long time - NgRx is a great option though and they are even working on their own solution with signals. But what I am doing in this video and in others recently is essentially a simplified version of NgRx/the Redux pattern. Redux is based around the idea of triggering actions that are handled by reducers to update the state - that is exactly what is happening in the video, I am nexting subjects (essentially actions) which are handled by reducers (this is happening in the constructor/subscribe step) to update the state (which is stored in a signal). For me the particular state management approach isn't the most important thing, it's whether that approach allows your code to be declarative/reactive.

    • @ErwinFRANCE
      @ErwinFRANCE 7 місяців тому

      @@JoshuaMorony ... and all is clear now. Thank you sir. Well done for all your work. You are very inspiring !

  • @JCPhlux2
    @JCPhlux2 7 місяців тому +2

    If you are not using firebase this is hard to adapt. Title should be "The CLEANEST Firebase authentication I've ever built with Angular"

  •  4 дні тому

    Why not use a resolver on the login page instead?

  • @haroldpepete
    @haroldpepete 8 місяців тому

    why do you use auth in injectiontoken? why not a simple function, could you explain me that part? why should be the difference between both approach?

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      I only want the factory function to run once and I want the result of that to be provided to anything that requests it - you could achieve something similar with a singleton/service, injection token is just a nice way to do it

    • @haroldpepete
      @haroldpepete 8 місяців тому

      @@JoshuaMorony ok, thank for taking the time and responding, you do a great job

  • @indrinator3819
    @indrinator3819 8 місяців тому +1

    About the defer thing: I usually handle auth-checking in the APP_INITIALIZER function, so I have all the required data in state before the application rendering. This usage of @defer seems a biit "hacky" for me.

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      I think it's fine to handle it this way (e.g. just wait until you know the user is authed before routing to the page) - but if the issue of "perceived performance" is an important consideration (e.g. showing things to the user even before the auth check has completed) then this wouldn't deal with that. The usage of defer also feels a bit hacky to me, but I haven't seen a way I like better if the goal is to display something immediately.

    • @user-qd6uu2mz4k
      @user-qd6uu2mz4k 8 місяців тому

      ​@@JoshuaMorony i have question to, i use auth-checking the same way on APP_INITIALIZER, and adding animation on index html, Is this also a performance issue?

    • @WaleedMohamed8
      @WaleedMohamed8 6 місяців тому

      ​we do the same with just simple animation in index. html and load the important data with auth checks in app initializer this way we know when the app starts if the user state and other states we need already loaded and ready for all other components

    • @WaleedMohamed8
      @WaleedMohamed8 6 місяців тому

      to be honest the defer approach is not clean at all and for no real reason in this demo just a hack for a problem already has a solution avaliable

  • @mawill432
    @mawill432 8 місяців тому

    BY YOUR POWERS COMBINED

  • @luke27456
    @luke27456 8 місяців тому +4

    Instead of using defer, couldn’t this be solved with a third state value for auth state, to represent when you don’t know whether a user is authed or not? You’d just need thin wrapper around firebase’s auth state, and/or some rxJS default vale magic (which you are far better at than I 😄)

    • @o_glethorpe
      @o_glethorpe 8 місяців тому

      It would be better than what he did, but its not good either, this should be solved in the routing layer

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      I do have a third value for auth state, which is "undefined" - the user() value is either "undefined" (unknown auth), "null" (not authenticated), or the user object (authed). So I have this info, but I still need to route to the login page immediately if I don't want to wait for the auth to complete, and there is still the problem of the login form flickering when the state transitions from "undefined" to the user object.

    • @mychmcg
      @mychmcg 8 місяців тому

      ​@@JoshuaMorony maybe I'm missing something, but why not only render the login form if user() == null

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      @@mychmcg hahaha yes, I'm pretty sure this would work just fine - specifically it would need strict equality with === so it doesn't match 'undefined'. No need to display the form at all if there is an active user, and it would display later if the user did become null, so should be all good I think.

  • @kibem.c
    @kibem.c 8 місяців тому

    Just wondering, how are you maintaining a login session?
    I see that there's no local storage/session storage used

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      It's handled by the Firebase SDK in this case

    • @kibem.c
      @kibem.c 8 місяців тому +1

      Thanks for the reply
      Just asking but is it possible for you to do a similar video but for APIs?

  • @djedaaa2232
    @djedaaa2232 7 місяців тому

    I love your videos, but i hate when people do something like this with Firebase when in reality not many people use it. Maybe make another video like this but with simple json server ?

  • @adarshdhital007
    @adarshdhital007 8 місяців тому +1

    Can you please,upload from the starting to end

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      Like building the app on video bit by bit from scratch? It would be too long of a video for my style of content - the source code is available in the description though, with the commits from when I actually built it too so you can see it in a step by step manner that way if you want

    • @adarshdhital007
      @adarshdhital007 8 місяців тому

      @@JoshuaMorony How can I login , I tried to clone the repo, and tried to create account , but I am not able to create . Why?

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      @@adarshdhital007 if you want to actually use the repo you will need to set up the local Firebase emulators, or do a prod build and add your own firebase config in the environments files

  • @Downicon3
    @Downicon3 8 місяців тому

    Resolver? Instead of defer

  • @user-ed2zi5qp9g
    @user-ed2zi5qp9g 8 місяців тому

    Why are you using defer() inside from()? Doesn't defer() already returns an observable without executing the promise until subscribed? I mean, I don't see the point on using from() operator

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +1

      Yes the defer/from combo is pointless, it can just be defer

  • @GeraldScholz
    @GeraldScholz 8 місяців тому +12

    Honestly it's way to complicated.

  • @swapnilpatel5743
    @swapnilpatel5743 29 днів тому

    haha, I see you've used 'firebase' and not '@angular/fire' as the later still doesn't have zoneless support. 😢

  • @MindlessTurtle
    @MindlessTurtle 8 місяців тому

    Yeah, the defer method smells like a hack, but I have no idea of a better solution.

  • @Henverx
    @Henverx 8 місяців тому +2

    Too much complexity for the very basic thing

  • @geomorillo
    @geomorillo 8 місяців тому +2

    You are using a cannon to kill a bug😂whathever happened to a simple form and JavaScript 😂

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому +3

      I would say I'm using a cannon to prevent bugs in everything else that would be built on top of this - I could get behind your sentiment if software was generally bug free and easy to maintain with just doing things the "simple" way, but I don't think that's the case. Most software is buggy and hard to maintain, so we come up with strategies to try and address that (maybe some of those strategies aren't good, but obviously I think this one is).

    • @mekbeb
      @mekbeb 8 місяців тому

      can you suggest a silver bullet if what we saw is a cannon? lol

  • @jerrytab4276
    @jerrytab4276 8 місяців тому

    Not a clean approach logics are in the components

  • @haroldpepete
    @haroldpepete 8 місяців тому +5

    There will come a time when only 1 or 2 people in the galaxy will understand angular, what a mess to do something so trivial, and angular doesn't look like javascript at all

    • @JoshuaMorony
      @JoshuaMorony  8 місяців тому

      The "complexity" here is more to do with the goal of creating reactive/declarative code than of anything to do specifically with Angular. I can agree there are complicated concepts here, but the point of using declarative code is specifically to create something that is not a mess - there are more strict rules with how things can occur and you can easily trace the dependencies of any "thing" to see how it is derived. Imperative code is more of a free for all - the ability to do anything anywhere and just update whatever you want looks easier initially, but becomes much more difficult when complexity grows.

    • @xucongzhan9151
      @xucongzhan9151 8 місяців тому +1

      Solve it with "if"s and imperative code, you are on the path to a great mess.
      Even React embraces Redux from the very beginning.

    • @haroldpepete
      @haroldpepete 8 місяців тому

      @@xucongzhan9151 but redux doesn't look like that, redux in react has a different approach, i preffer angular over other javascript technoligies, but you have to admit that angular has a weird way, it doesn't look like javascript

  • @iantuts5030
    @iantuts5030 2 місяці тому

    how can I use rxfire?