This article is a continuation to the previous one. In which we created a MEAN Stack Application with Node JS API for user registration. Here we extend the same project by adding client-side Angular 6 application with User Registration Form in MEAN Stack.
GitHub link up-to this article : https://goo.gl/EE2TuQ
MEAN Stack Tutorial Hierarchy
- CRUD Operation – Insert Update View and Delete.
- User Registration
Node JS Back End.
Angular 6 Front End (this one). - JWT User Authentication
Node JS Back End.
Create Angular 6 Application
Following angular-cli command will create a new angular 6 application with some default npm packages.
ng new Angular6
Application name is also Angular6 and our application structure will be as follows.
● src
+---● app
| +--● user
| | |--user.component.ts|.html|.css
| | +--● sign-up
| | | |--sign-up.component.ts|.html|.css
| |
| |--● shared
| | |--user.service.ts
| | |--user.model.ts
| |
| |--app.module.ts
| |--routes.ts
|
|--index.html
As per the structure, we have one parent user component and one child sign-up component. Inside shared folder we need to create service and model class files for user. For that we can use following angular-cli commands.
// user component
ng g c user
// sign-up component - from user folder
ng g c sign-up
// service class - from shared folder
ng g s user
// model class - from shared folder
ng g class user --type=model
Define User Model Class
Let’s add required properties inside User model class.
In server side Node JS API, we hade one extra property SaltSecret for encrypting user password. Here in client side we don’t need that property.
Let’s Design User Registration Form
We will design the registration form using sign-up component. For that we need a property of user model inside sign-up component typescript file. For that we will start from UserService class.
Here selectedUser property is defined inside UserService Class. Now we can inject this service class inside sign-up component, Thereby we can access the selectedUser property for designing user registration form.
Here we injected UserService Class and we have one additional emailRegex property for email validation .
Now I want to update styles.css with all required css rules for the entire application.
/* You can add global styles to this file, and also import other style files */
@import url('https://fonts.googleapis.com/css?family=Poppins');
/* BASIC */
html {
background-color: #56baed;
}
body {
font-family: "Poppins", sans-serif;
height: 100vh;
}
a {
color: #92badd;
display:inline-block;
text-decoration: none;
font-weight: 400;
}
h2 {
text-align: center;
font-size: 16px;
font-weight: 600;
text-transform: uppercase;
display:inline-block;
margin: 40px 8px 10px 8px;
color: #cccccc;
}
/* STRUCTURE */
.wrapper {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
width: 100%;
min-height: 100%;
padding: 20px;
}
#formContent {
-webkit-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
background: #fff;
padding: 30px;
width: 90%;
max-width: 450px;
position: relative;
padding: 0px;
-webkit-box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
text-align: center;
}
#formFooter {
background-color: #f6f6f6;
border-top: 1px solid #dce8f1;
padding: 25px;
text-align: center;
-webkit-border-radius: 0 0 10px 10px;
border-radius: 0 0 10px 10px;
}
/* TABS */
h2.inactive {
color: #cccccc;
}
h2.active {
color: #0d0d0d;
border-bottom: 2px solid #5fbae9;
}
/* FORM TYPOGRAPHY*/
input[type=button], input[type=submit], input[type=reset] {
cursor: pointer;
background-color: #56baed;
border: none;
color: white;
padding: 15px 80px;
text-align: center;
text-decoration: none;
display: inline-block;
text-transform: uppercase;
font-size: 13px;
-webkit-box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
margin: 5px 20px 40px 20px;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
-o-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
background-color: #39ace7;
}
input[type=button]:active, input[type=submit]:active, input[type=reset]:active {
-moz-transform: scale(0.95);
-webkit-transform: scale(0.95);
-o-transform: scale(0.95);
-ms-transform: scale(0.95);
transform: scale(0.95);
}
input[type=submit]:disabled{
background-color: #f5f6f6;
color: #7d7d7d;
}
input[type=text],input[type=password] {
background-color: #f6f6f6;
border: none;
color: #0d0d0d;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 5px;
width: 85%;
border: 2px solid #f6f6f6;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
}
input[type=text]:focus,input[type=password]:focus {
background-color: #fff;
border-bottom: 2px solid #5fbae9;
}
input[type=text]:placeholder {
color: #cccccc;
}
input[type=text].invalid-textbox,input[type=password].invalid-textbox{
border-bottom: 2px solid #ed5558;
}
label.validation-message{
color:#ed5558;
}
/* ANIMATIONS */
/* Simple CSS3 Fade-in-down Animation */
.fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
@-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
@keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
/* Simple CSS3 Fade-in Animation */
@-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fadeIn {
opacity:0;
-webkit-animation:fadeIn ease-in 1;
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.fadeIn.first {
-webkit-animation-delay: 0.4s;
-moz-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.fadeIn.second {
-webkit-animation-delay: 0.6s;
-moz-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.fadeIn.third {
-webkit-animation-delay: 0.8s;
-moz-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.fadeIn.fourth {
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
/* Simple CSS3 Fade-in Animation */
.underlineHover:after {
display: block;
left: 0;
bottom: -10px;
width: 0;
height: 2px;
background-color: #56baed;
content: "";
transition: width 0.2s;
}
.underlineHover:hover {
color: #0d0d0d;
}
.underlineHover:hover:after{
width: 100%;
}
/* OTHERS */
*:focus {
outline: none;
}
#icon {
width:60%;
}
* {
box-sizing: border-box;
}
.alert {
padding: 20px;
background-color: #f44336; /* Red */
color: white;
margin-bottom: 15px;
}
.success{
padding: 20px;
background-color:#249424; /* Green */
color: white;
margin-bottom: 15px;
}
Registration form can be designed inside the sign-up.component.html as follows.
Here we have 3 input-fields for fullName, email and password with proper validations. Following validations are implemented inside the form
- FullName – Required
- Email – Required & Email Pattern
- Password – Required & Min Length
This form is designed using Template Driven Approach. So we have to add FormsModule in app.module.ts file as follows.
Call Node JS API From Angular 6
Now I will create a function inside UserService class in-order to call Node JS API From the Angular 6 Application. This function will make a POST request to Node JS API to insert new user details.
Post request is made through HttpClient object and hence we need to add HttpClientModule in app.module.ts file.
apiBaseUrl is retrieved from environment.ts file. which we have stored inside the file as follows.
Form Submit Event
Now let’s implement submit event for the form element using ngSubmit directive.
onSubmit function will be called when the form as whole is valid( ie. signUpForm.valid). Now let’s define the function inside the component.
Inside the onSubmit function we called postUser function from UserService class. So that it will insert a new user in MongoDB. resetForm function is used to reset form controls to their initial state.
Two additional properties showSucessMessage & serverErrorMessages are added to show success and error notification respectively. Inorder to show these notifications, we need to add notification div elements in component html.
Routing Configuration
Before adding routing, we need add routing-outlet in proper places. So first of all I’ll replace default text from app.component.html(default component) with routing-outlet tag. As per the application structure user component will be the parent component for sign-up component. So inside the user component we need to wrap the registration form as follows.
Now let’s add a new file for routing – routes.ts.
signup route is used for user registration form and same route will shown for default route also. Now we need to add this appRoutes constant in app.module.ts using RouterModule.
In the next article we’ll implement Node JS JWT Authentication inside this same MEAN Stack Project.
from registered user i want upload images..
It Works for me!!!But when I Enter and hit sign up button, it shows ‘Something went wrong.Please contact admin.’ message..Please solve this man!!
Clearly follow yours tutorial but after running it only shows signup heading without any text boxes,button…nothing Appears!!!
sir what is envioment
refers where this application is hosted.
it could be either development or production
the screen i saw when running is only blue background. Cant see the Text fields. Like the routing not working at all
Hi there,
I followed each step in this tutorial and the previous one, and was planning on moving on to the next parts, but nothing happens when I click sign up in my form. Any thoughts??
Thanks a lot!
Thanks a lot sir for the tutorial, courage with angular6.
Please can you make a tutorial with angular and node that
sends emails to a users email.? Pleeeaaase!!!
i want to forget password reset please extend your tutorials / project with forget password reset
Thanks a lot Shamseer for your Latest MEAN Stack Registration Video Series at Youtube. I really learned a lot and using it for my project. I would like to request you a bit more if possible. My requests below :
1. User gets and email after registration with an activation link. He has to click the link within 24 hours then his information will be saved in to database for future login purpose.
2. A Login module (backend and frontend both). After login, a user will be redirected to a normal page/view.
If possible please continue this series as per my request. More reward will be there for sure :) .. Thanks a lot and take care.
Saif
Thanks for the comment, I’m on my way to expand the project with jwt authentication.
Great, eagerly waiting for Part-3 .. Cheers :)
Next Part : Jwt User Authentication in Mean Stack : https://goo.gl/wmGMUw.
you need add app.component.html file
It is there on GitHub but not in article, because it only contains router-outlet tag