- 00:00:01 in our view the five firebase meter
- 00:00:04 project here we already achieved a lot
- 00:00:07 and over the last videos we implemented
- 00:00:10 authentication we're now able to sign
- 00:00:12 users app and in the one problem we
- 00:00:16 still have there is we don't really
- 00:00:17 communicate the current state of our
- 00:00:20 authentication though so click sign up
- 00:00:22 here well I get this automatically
- 00:00:24 generated html5 error but we don't get
- 00:00:28 any error besides debt if I sign up with
- 00:00:31 a valid form data but a password which
- 00:00:34 actually is not long enough I don't get
- 00:00:36 any feedback at all so that is not the
- 00:00:39 best way of handling this form what be
- 00:00:41 nice to see when something is happening
- 00:00:43 would be nice to get some authentication
- 00:00:46 errors for example let's implement that
- 00:00:49 in this video
- 00:00:53 so I want to basically display the
- 00:00:57 current state or information about the
- 00:00:59 current state of indication to the user
- 00:01:02 for that we of course will use UX
- 00:01:05 instance our state management system and
- 00:01:08 there I want to track two things I want
- 00:01:11 to track if we're currently loading data
- 00:01:14 so if I want to display like a spinner
- 00:01:16 because we're currently sending data to
- 00:01:18 the server and waiting for a response
- 00:01:19 and I want to display if we get any
- 00:01:22 authentication errors now for that I'll
- 00:01:25 simply go up in my state and here
- 00:01:29 besides my loaded meetups on the user
- 00:01:31 I'll add cue other things I'll add a new
- 00:01:34 field which is called loading which will
- 00:01:37 set to false initially because initially
- 00:01:39 we are loading and then I'll also have a
- 00:01:43 field of error which I'll set to null
- 00:01:45 because initially I also don't assume to
- 00:01:48 have an off error now we could of course
- 00:01:51 also just name this error for now and
- 00:01:54 later see if we can reuse that on
- 00:01:56 different components because we might
- 00:01:58 have different areas in our application
- 00:02:00 where we reach out to a server and then
- 00:02:02 it might be nice to have a reusable
- 00:02:03 error state we can use so with these two
- 00:02:07 new state fields here I need new
- 00:02:11 mutations to change them for example I
- 00:02:14 want to have a set loading mutation
- 00:02:17 where I of course mutates the state and
- 00:02:19 when I get a payload to either set it to
- 00:02:22 loading or to well to not loading
- 00:02:24 because we are done we got everything we
- 00:02:26 want so here I will simply set state
- 00:02:30 loading equal to payload so payload
- 00:02:33 should be true or false depending on
- 00:02:35 whether we are loading or not so thatís
- 00:02:38 what I'll set up here and then I also
- 00:02:41 want to have a set error commit mutation
- 00:02:47 that is what's called here I also
- 00:02:49 receive a payload and that of course
- 00:02:50 will be my error so we'll set state
- 00:02:53 error equal to payload that would be a
- 00:02:57 fitting mutation we could also add a
- 00:03:00 clear error mutation and of course you
- 00:03:04 could all just pass a payload of null
- 00:03:06 here clear
- 00:03:07 error but I think it is a bit more
- 00:03:10 explicit about what we do here if we
- 00:03:12 have a mutation really focusing on this
- 00:03:15 sole purpose where I said state error
- 00:03:18 equal to null so with that we got new
- 00:03:22 mutations to work with loading and error
- 00:03:25 states now we can use them for example
- 00:03:28 in signing a user up right at the start
- 00:03:31 of course once it's said loading to true
- 00:03:33 because no matter if it succeeds or not
- 00:03:35 we are loading we are reaching out to
- 00:03:38 the web so here it is action I
- 00:03:42 definitely want to commit set loading
- 00:03:45 and I want to set this to true because I
- 00:03:48 am loading on the other hand whenever we
- 00:03:52 reach the better block here where we got
- 00:03:55 a user we certainly are not loading any
- 00:03:57 more so here we can again commit set
- 00:04:00 loading but here set it to false and of
- 00:04:03 course I also want to set loading to
- 00:04:05 false if we get an error because even
- 00:04:07 though we got an error the loading
- 00:04:09 process is finished there's no more data
- 00:04:11 to come on the other hand if we do get
- 00:04:14 an error there's one other thing I want
- 00:04:15 to commit I want to set set error queue
- 00:04:19 error and this specific error here
- 00:04:22 thrown by firebase happens to have a
- 00:04:25 message property we could see that in
- 00:04:28 one of the earlier videos and you can
- 00:04:30 confirm that if you assembly run
- 00:04:33 authentication open the console each our
- 00:04:35 script console because we are logging
- 00:04:37 the error here and then have a look at
- 00:04:39 the error so there we have a message
- 00:04:41 property the following one here let me
- 00:04:45 show this to you if we enter valid data
- 00:04:48 by the password which is not long enough
- 00:04:50 and I click sign up here we got a
- 00:04:52 message object as you can see password
- 00:04:55 should at least be 6 characters so this
- 00:04:57 is the property we can access there and
- 00:05:00 that's the one we'll then use so that's
- 00:05:03 something we have to rely on so with
- 00:05:04 that I'm also saving the error on the
- 00:05:07 other hand right at the start when we
- 00:05:09 start loading we probably want to also
- 00:05:13 run clear error so this mutation here
- 00:05:17 because if you're sending a new request
- 00:05:20 we want you
- 00:05:21 here any previous barrows probably so
- 00:05:23 that looks like a good a decent setup
- 00:05:25 here of course I'll repeat it for
- 00:05:29 designing process are all the commit
- 00:05:32 loading and clear errors here at the
- 00:05:34 beginning all set
- 00:05:36 loading to false once we have well
- 00:05:39 either a success or an error case but I
- 00:05:42 will also set the air or here like that
- 00:05:45 with that we're managing all that in
- 00:05:47 view X we're managing our state here now
- 00:05:50 we have to take advantage of the state
- 00:05:51 in our views for example to show a
- 00:05:54 spinner whilst we are loading or to show
- 00:05:57 an error if we got one let's start with
- 00:06:00 the error and for that let's go back to
- 00:06:05 beautify chess and here under components
- 00:06:08 this alert component looks alright we
- 00:06:11 can add such an alert at the top of our
- 00:06:13 page to show it whenever we got an error
- 00:06:16 actually I want to have a closeable
- 00:06:18 alert though so that we can dismiss it
- 00:06:20 as a user and we can simply have a look
- 00:06:22 at the code here as always we see the
- 00:06:24 alert is the component this mis'able has
- 00:06:27 to be added so that we get this X symbol
- 00:06:29 to close it and then we bind it either
- 00:06:33 to the model to open close it's
- 00:06:35 triggered by a property or since we
- 00:06:38 model it's just a wrapper for an input
- 00:06:40 event which is emitted and a valuable
- 00:06:42 property you can pass in we might also
- 00:06:45 just listen to the input event to clear
- 00:06:48 our errors but I'll come back to that
- 00:06:50 let me copy that code here and I want to
- 00:06:53 add it in my signup W file here at the
- 00:06:56 very top I want to do the same in my
- 00:06:59 sign-in file so why don't we create a
- 00:07:02 utility component for that stored in a
- 00:07:04 new directory maybe all name is shared
- 00:07:07 because will hold some shared components
- 00:07:09 and here I'll name it alert that view
- 00:07:12 was the file name and here I'll add a
- 00:07:15 template like that and injured it like
- 00:07:20 that so now we got the alert here now
- 00:07:24 with that I want to set this from info
- 00:07:27 to let's have a look
- 00:07:29 maybe yeah the error alert so that has
- 00:07:32 the error property then on it so that
- 00:07:35 you error dismissible and I don't want
- 00:07:38 to use the model instead I want you just
- 00:07:41 listen to the event and bind it through
- 00:07:45 a different source
- 00:07:46 so here I'll add a script and on this
- 00:07:53 script here or in this script
- 00:07:57 I'll now export my default object as
- 00:07:59 always and here I'll simply add a method
- 00:08:03 on clothes where I will omit a new event
- 00:08:08 with this dollar sign eMED emit using
- 00:08:11 this built-in event emitter you chase
- 00:08:13 offers and I will name it dismissed you
- 00:08:16 can choose any name you want here and
- 00:08:18 that's actually all I won't pass any
- 00:08:20 data with that now here I don't use the
- 00:08:24 model therefore but I just mind you add
- 00:08:26 input and here I then execute on clothes
- 00:08:31 like that now let's see if that works
- 00:08:35 like that if I go to the signup to view
- 00:08:37 file here I'll add and UV layout row at
- 00:08:40 very top where I will hold this alert
- 00:08:43 later on with a reflex element X as 12
- 00:08:48 and on smaller screens it should also be
- 00:08:51 a bit smaller and in there and I want to
- 00:08:54 include that alert component I will make
- 00:08:56 it a global component so in the main dot
- 00:08:58 JS file I'll first of all import it so
- 00:09:02 I'll alert import the alert component
- 00:09:05 from dot slash components shared and
- 00:09:10 then the alert stop you file like that
- 00:09:12 and with that being imported I can now
- 00:09:15 register it here with view component and
- 00:09:19 then I'll name it app alert the alert
- 00:09:23 component like that so that's the
- 00:09:27 component registered we can now use that
- 00:09:29 selector here and you sign up as view
- 00:09:31 file to import it like this and here I
- 00:09:34 now want to listen to the dismissed
- 00:09:36 event that's the custom event we're
- 00:09:39 emitting here like this happens or this
- 00:09:41 is emitted if we actually do
- 00:09:42 miss the alert so here I want to listen
- 00:09:46 to that and I want to execute on
- 00:09:48 dismissed a method which I of course
- 00:09:51 have to implement here and yes you could
- 00:09:54 do that differently I'm just using this
- 00:09:56 setup because theoretically with that
- 00:09:58 you could use that alert component here
- 00:10:00 to not just display errors but anything
- 00:10:03 which can be dismissed and if I were to
- 00:10:05 handle on clothes in here in the alert
- 00:10:07 component and reach out to view X to
- 00:10:10 clear errors then this alert would be
- 00:10:12 bound to only handle errors because it
- 00:10:15 manipulates the state instead this is a
- 00:10:18 dump component it doesn't know what I
- 00:10:20 use it for and yes you will have to
- 00:10:22 adjust your text view output here but
- 00:10:24 with that this also means you can use it
- 00:10:27 by simply adding or omitting this
- 00:10:29 dismissed event and then we handle on
- 00:10:31 this mist in the component where we know
- 00:10:33 what we actually want to display so here
- 00:10:36 I'll add a new method on dismissed and
- 00:10:39 for now I will simply log it to see if
- 00:10:43 that works
- 00:10:43 dismissed alert now right now if we go
- 00:10:48 to the signup page again and we load
- 00:10:53 this we should always see the alert we
- 00:10:56 don't I'm including Yeller here well yes
- 00:11:00 make sense by default it's not showing
- 00:11:02 so here we have to sum a binary value
- 00:11:05 property either to true or false so bind
- 00:11:08 with a colon in front of it to bind it
- 00:11:10 to a dynamic value and it should always
- 00:11:13 be true here though because I always
- 00:11:15 want to show it now we see the error
- 00:11:18 here now if I click on that we see this
- 00:11:23 missed alert whenever I click it so
- 00:11:25 that's working with that we got the
- 00:11:27 logic we need to now also control when
- 00:11:30 we show it and I won't trigger that here
- 00:11:33 through value even though I could do
- 00:11:35 that but I can simply decide if I want
- 00:11:38 to attach this whole row here with vs
- 00:11:41 and there I now need to track we have an
- 00:11:44 error or not so for that let's go back
- 00:11:47 to the store and add a gather and here
- 00:11:50 I'll name this error I'll of course
- 00:11:55 X
- 00:11:55 state here and I will return state error
- 00:11:58 just like that whilst of already here I
- 00:12:01 can also return load in here because
- 00:12:04 that's the other news state we added an
- 00:12:06 L needed is to return state loading like
- 00:12:10 that so now I'm returning the error back
- 00:12:13 can you sign up a view file I can now
- 00:12:15 add a new computed property which I'll
- 00:12:18 also name error because here I will
- 00:12:21 return this store gathers error so the
- 00:12:25 error we just added with that error
- 00:12:28 property here this is now what I want to
- 00:12:31 bind here if that is no it will not be
- 00:12:34 displayed if it's anything but now we
- 00:12:36 will see the error now in on this missed
- 00:12:39 I therefore here one to dispatch a new
- 00:12:42 action this store dispatch clear error
- 00:12:47 of course because I want to get rid of
- 00:12:50 the error if I get rid of the error the
- 00:12:52 error getter will return null again and
- 00:12:54 that will then trigger we if to remove
- 00:12:57 this road and therefore the alert and it
- 00:13:00 will reappear if we get a new error now
- 00:13:03 of course I want to pass the error text
- 00:13:05 into that alert component so I will bind
- 00:13:08 with call and text to a text property
- 00:13:12 and pass error that message keep in mind
- 00:13:15 error has to be object which has a
- 00:13:18 message that's just something I define
- 00:13:21 in my application it's even now in which
- 00:13:23 case the thousand get executed because
- 00:13:25 the whole row isn't attached or it is
- 00:13:28 not object and in this case it needs to
- 00:13:30 have a message property now of course
- 00:13:33 the problem is that app alert doesn't
- 00:13:36 know a text property we could bind to so
- 00:13:39 we have to go to alert and add it why
- 00:13:41 are the props property here I want to
- 00:13:45 bind to a text property which I then
- 00:13:48 output here inside of my alert like this
- 00:13:51 with this setup let's save this and
- 00:13:53 let's see if it works let's open the
- 00:13:55 console enter something here like an
- 00:13:59 invalid password and let's click signup
- 00:14:01 and we do get the error here password
- 00:14:05 should be at least 6 characters close
- 00:14:07 this
- 00:14:08 then we get an error unknown action-type
- 00:14:11 clear error let's see did I miss type
- 00:14:14 that the action is named the action
- 00:14:19 doesn't exist we only have the mutation
- 00:14:21 right
- 00:14:21 so I obviously need to add it as action
- 00:14:25 to clear error because I'm dispatching
- 00:14:28 it as action and I want you to do that
- 00:14:31 so here all extract commit again and
- 00:14:35 here I will then commit clear error like
- 00:14:42 that I didn't have to do that for set
- 00:14:45 error because right now I'm only
- 00:14:47 committing set error here as part of
- 00:14:49 other actions which is fine so now we
- 00:14:51 have a clear error action let's try it
- 00:14:54 again let's maybe try a valid password
- 00:14:56 for the email address which is already
- 00:14:58 taken and we see the email address is
- 00:15:01 already in use by another account so
- 00:15:02 it's really nice that firebase gives us
- 00:15:04 this nicely formatted error messages now
- 00:15:07 closing also works they submit again I
- 00:15:11 get it again so that's nice as a last
- 00:15:14 piece in this video I want to disable
- 00:15:17 the button and show a spinner inside the
- 00:15:19 button whilst we are waiting for the
- 00:15:22 response and the cool thing is beautify
- 00:15:25 actually makes that simple if you check
- 00:15:27 out the button configuration here and
- 00:15:29 you scroll down a little bit you will
- 00:15:32 see that you have loaders which are
- 00:15:34 buttons you can click queue for example
- 00:15:37 see a spinner here here the icon loader
- 00:15:40 jitter looks pretty good so let's
- 00:15:42 inspect that code and you see that I can
- 00:15:45 loader your uses disks and with a loader
- 00:15:48 icon side of it and then also simply
- 00:15:53 gets disabled when it is loading and
- 00:15:55 binds to loading property when it is
- 00:15:57 loading so that is what I need to
- 00:16:00 implement I'll do that you signup to
- 00:16:03 view file here in my button where I have
- 00:16:05 sign up right now I'll add something
- 00:16:08 after sign up this span I copied here so
- 00:16:12 this span which will actually display DD
- 00:16:16 spinning circle whenever it is loading
- 00:16:20 so like that
- 00:16:22 I also now of course need to bind to
- 00:16:26 disable and to loading when it is
- 00:16:28 loading and for that I will bind to a
- 00:16:30 loading property so loading will be
- 00:16:33 bound to loading and loading here is
- 00:16:36 just a property made available by the V
- 00:16:38 button element whilst loading here is a
- 00:16:40 property I have to define and I will
- 00:16:43 define it as a computed property because
- 00:16:46 where will I get loading where will I
- 00:16:48 get this information if it's loading
- 00:16:50 from from my view X state right because
- 00:16:54 here we have that state or use the
- 00:16:57 mutation here's the loading state and we
- 00:17:00 set it to loading or to not loading in
- 00:17:03 our actions depending on whether we're
- 00:17:05 just starting or finishing so I can use
- 00:17:08 that information extracted here from the
- 00:17:10 Gator we also defined this store gathers
- 00:17:14 loading that's now referring to that
- 00:17:18 Gator we define down here to get that
- 00:17:21 loading state and with that we got
- 00:17:23 everything we need now let's try it out
- 00:17:26 let's go back to the application here
- 00:17:28 let's reload it maybe and let's try this
- 00:17:31 again let's submit a valid value here
- 00:17:34 click sign up yeah we saw it but let's
- 00:17:40 try it invalid one again it's not
- 00:17:43 spinning whoops let me quickly enter
- 00:17:45 some invalid values it's not spinning
- 00:17:47 the reason for this is that we didn't
- 00:17:50 copy all the code here just loading the
- 00:17:54 HTML code isn't enough notice the custom
- 00:17:58 loader class that isn't provided by
- 00:18:00 beautify by default instead you see the
- 00:18:03 style tab here here if you CSS code you
- 00:18:07 rarely have to do that but some
- 00:18:09 component examples here use as CSS code
- 00:18:13 so always check all the tabs here if
- 00:18:15 something isn't working so in this case
- 00:18:18 I'll just copy the style here and I
- 00:18:21 could copy it into my signup the view
- 00:18:22 file but I actually want to use the same
- 00:18:25 logic and logic in different places so
- 00:18:28 all instead use my main dot stylist file
- 00:18:31 where I change the theme
- 00:18:33 and here you cannot actually just copy
- 00:18:35 in normal CSS code you don't have to use
- 00:18:38 stylus syntax that will work so I'm now
- 00:18:41 I'm defining the custom loaded class
- 00:18:43 globally and with dead if we now let it
- 00:18:47 compile we try this again now you see
- 00:18:51 spend firebase is just so super quick
- 00:18:53 that you don't really see but if you
- 00:18:55 watch closely it does spin before we get
- 00:18:57 the error so that's nice let's now do
- 00:19:00 the same for these sign-in page that
- 00:19:02 should of course be simple we got the
- 00:19:04 logic in this signup page I'll first of
- 00:19:07 all copy the whole button here go over
- 00:19:10 to sign in and replace the button here
- 00:19:13 just make sure to rename it to sign-in
- 00:19:15 and what else did we change
- 00:19:18 well we added that alert at the top so
- 00:19:20 let's add the layout that row with the
- 00:19:23 alert at the top of that form too so
- 00:19:26 right after the initial container the
- 00:19:29 missing thing now is that we need to get
- 00:19:31 the computed properties so loading and
- 00:19:34 error and that we'll need to add the on
- 00:19:37 dismiss method so I'll do that
- 00:19:39 in sign in got view here first of all
- 00:19:42 add my Q computed properties and all the
- 00:19:47 copied on dismissed method from the
- 00:19:49 signup to view file and add it here in
- 00:19:52 on sign in the sign in to view file I
- 00:19:56 can get rid of the console log with the
- 00:19:58 dismissed error I guess so let's save
- 00:20:01 this and let's try it out that should be
- 00:20:03 all and that shows how reusable that
- 00:20:05 alert component already is here on the
- 00:20:09 sign-in page if we reload this and we
- 00:20:11 well try to sign in with something which
- 00:20:14 doesn't exist like test for didn't
- 00:20:17 create that there isn't a user that's
- 00:20:19 that's great and if we use a valid email
- 00:20:21 address but a wrong password well either
- 00:20:26 the user is invalid or the password so
- 00:20:28 we get an error message here Q and we
- 00:20:31 can dismiss it now let's try a valid
- 00:20:33 login data attempt here that's still
- 00:20:37 working so with that we enhance the the
- 00:20:41 off process we're using this space now
- 00:20:43 we're giving a better feedback to the
- 00:20:45 user
- 00:20:46 super important any application because
- 00:20:48 you obviously want to allow the user to
- 00:20:50 know where he is and what's happening I
- 00:20:53 hope this was helpful
- 00:20:54 can't wait to see you the other videos
- 00:20:56 bye