Login screen for NativeScript App (NS-Vue)
Tags: nativescript, login, nativescriptvue, fetch
Published: 2021-07-10 18:31:57

Over the last three weeks at work I've been building out a mobile application for our captains to use.  We chose NativeScript as it's cross platform, meaning I / we don't have to develop individual apps for both android / iOS.  The cool thing about NativeScript is you can choose your "flavor", meaning it can be written in javascript, typescript, Vue, Vue with typescript, angular, svelte, ionic, react, I mean pretty much any major front end framework.  Since I come from a Vue "background" I chose Vue. Out of the box as well with NS, you can choose to use a template, and I chose to use the drawer navigation because I found it to be very useful for our needs and it allows expandability if for some reason I have / get to upgrade.  

So setting up your environment for NS development is pretty much a day worth of work on it's own.  [NativeScript docs](https://docs.nativescript.org/) will give you the best chance of helping you set up your environment.  After you run through the CLI setup for your app you can at anytime type `tns doctor` and you can see what is still missing to successfully run your app.  Fair warning iOS was relatively simple but android gave me some problems.  All I can say is may the odds be forever in your favor.  So lets say you install and run the doctor command and everything is gucci, your next thing to do is add the specific platforms `tns platform add <platform>` and once your platform(s) are added you can run `tns run <platform>` but after that don't forget this flag!!!!!!!!!!!  `--no-hmr`, which will allow for hot reloading.  So the full command is `tns run ios --no-hmr`.  So if you run that and after some time an iPhone or iPad pops up congratulations, if not just look at what the console tells you and google will be your best friend.  

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykgrywwqxbxi2owf9n7p.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/neld5gqvdj7t9ybcdjp6.png)

So if installed properly and ran properly this is your basic nativescript drawer app, and yes it is bare and basic, but the fact that you get all of this out of the box, well I think it's pretty amazing.  So being that I don't need / want some of the basic views I basically deleted everything except the drawer navigation and app component.  I also like to keep my components a tad more organized and for my Login component that I will be building I created and Auth folder and created Login.vue inside of it.  If you look in the App.vue you'll see the main component that they proved is Home and I'll be replacing it with my Login vue because when this app loads the first thing that should come up is the login screen, I mean otherwise how could we get specific data?  

What does a login screen consist of?  Well I'll need 2 inputs one for email and one for password as well as a button.  So one thing I forgot to mention is that even though we are using "vue" we still have to use NS, which has specific components, that means you cannot use normal divs, spans, and other HTML elements that you are used to.  Also each "view" or page on the app needs to be wrapped in a NS Page element.  I also decided to add our logo to the main login view cause it would look nice.  I just downloaded an image from our site and added it to root of the app directory.  So looking at the nativescript components available to me looks like I'll be using TextField and Button, and I'll need to wrap them in something and in this case I decided to use StackLayout.  Also one thing cool about NS is that they have an ActivityIndicator (spinning / loading wheel) out of the box.  So going to add that for whenever I "hook" it all up and I'll be using it throughout the app as a loading state.  

```
<template>
    <Page class="page">
        <StackLayout>
            <StackLayout class="logo-container">
                <Image src="~/logo.png" stretch="aspectFit" class="logo"/>
            </StackLayout>
            <StackLayout class="form">
                <ActivityIndicator color="#165E7B" :busy="loading" />
                <StackLayout :class="loading ? 'input-field opaque' : 'input-field'">
                    <TextField v-model="email" hint="Email" class="input" :isEnabled="!loading" />
                </StackLayout>
                <StackLayout :class="loading ? 'input-field opaque' : 'input-field'">
                    <TextField v-model="password" hint="Password" :secure="hidePassword" class="input" :isEnabled="!loading" />
                </StackLayout>
                <StackLayout :class="loading ? 'input-field opaque' : 'input-field'">
                    <Label class="input" @tap="hidePassword = !hidePassword" v-if="password.length">
                        <FormattedString>
                            <Span class="input-show" :text="hidePassword ? 'Show Password   ' : 'Hide Password   ' "/>
                            <Span class="fas input-show-pw-icon" text.decode="&#xf06e;" />
                        </FormattedString>
                    </Label>
                </StackLayout>
                <Button @tap="login" text="Login" :class="loading ? 'btn btn-primary opaque' : 'btn btn-primary'" :isEnabled="!loading" />
            </StackLayout>
        </StackLayout>
    </Page>
</template>
```

So that's my component, and please don't worry abut all the conditionals and what not we'll go over the basics.  I'm using v-model to use 2 way data binding in the text inputs.  I also decided to add the hidden password attribute with a little button so that I can hide / show it.  Labels / Buttons have the @tap method where you can run a function when the item is "clicked" or tapped.  So for now I'm not going to connect to my API I just want to mock a login.  So basically when the login button is tapped I want to check to makes sure there are not empty inputs and if that condition is met we will redirect to the "home" blade.  If you recall I removed all of their default vues that I would not be using but I also did this after I got this mocked login.  You do whatever works for you but since I'm completely new to NS I decided to go as basic and "slow" as possible so that I could try and learn it the right way.  

```
            login() {
                if(this.email !== '' && this.password !== '') {
                    this.$navigateTo(Home, {
                        animated: true,
                        transition: {
                            name: "slide",
                            duration: 200,
                            curve: "ease"
                        }
                    });
                }
            }
```
And remember that I replaced the Home component in App.vue with Login and have this: 
```
<template lang="html">
    <RadSideDrawer ref="drawer" drawerLocation="Left" gesturesEnabled="true" :drawerTransition="transition">
        <StackLayout ~drawerContent backgroundColor="#ffffff">
            <DrawerContent/>
        </StackLayout>
        <Frame ~mainContent ref="drawerMainContent">
            <Login />
        </Frame>
    </RadSideDrawer>
</template>
```
Now you'll have to import the proper components in like you would in Vue and then you can test out your new mocked login.  So over the next couple weeks I'll kinda go through what packages I'm using and how I'm connecting to the API, handle errors, manage state, all the basics.  If there is something specific you want / are looking for just message me or leave a comment here.  This will probably be more boring posts since I don't really have a whole lot of experience or any for that matter with NS and half the time I'm just regurgitating docs and other blogs I've read.  As for now you all have a great weekend!!!