{"componentChunkName":"component---src-templates-blog-post-js","path":"/intro-to-nodejs-part-5/","result":{"data":{"site":{"siteMetadata":{"title":"tech-blog","author":"Alamgir Qazi"}},"markdownRemark":{"id":"ef3b36a7-86a6-59d5-b1d2-a4f0ea48f0c8","excerpt":"This is the part 5 of post Intro to Nodejs - part 4. In this post, we will connect our Node.js App with an Ionic app. Most software…","html":"<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/d9199/node-js.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACKElEQVQoz32Sz2vTYBjHnzfVHedglzpRUUSTTE3UJq9jS9I0s/h7BwXdZbUyRUS9+A8sWZqijrGDN0+iB0U8CP4Nw7Vqi9OLStllIHrx5kWI3ydpvWngy/O27/N+np9E//m8sk2ua5ED4ayUfUkD/fMbOAQnJdXCI7SwqlPc0ShqaVSdscgtWzTllDL4wNevSJo+ZVM9MSlc06nR1WjhjUpLX8YzoJJFr0hlfvkwLb7TlLClKotvNcU+OAFQBhmBbkIFSMC/gP+VNCWK32uCgZBY+poD8+iIeqVhEEAUtlWKYE9fKgm+v3/3Hvt9h1+RA0wck2iFpEe/D1Ccw4YYCqDCjgH02g9kpZ4YFLU1B1k+gfXrTYP8aWnxPQPLFXsYQMuZlC9hq5UTNleko0UeNI6StzHwF/TM8+S3WmgW4476A9mlsD+vrxhjyKSH7B+XfXsT572AbpyfK7XxZvXGQ2M0WVdnUPZVAO8kH/RhBm6cnbW3Ati9eOvorrir9vrAzWvLZtFz5Wf4vIB6AI71gc+Dqtz+Kt29BRkybB66DeAIA/fjESH9fUQXlOYnVYXTA0zZqDdMLtmEz1NIIigP6RBKXoHdeWbWomhN34H+TUJ7eDvyoQCIhzREASUfeSAq95JqkSnQ278r47q24KFMHcfZyVcoauk86Ww4zfUcKPgSD8Uo+QwUUVstoGwxF5m8c9ma9Ncr80c/+TdVz9kMFBmwo4k0vUx/ANst4OwYAzGqAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"Intro To Node.js\"\n        title=\"\"\n        src=\"/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/fcda8/node-js.png\"\n        srcset=\"/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/12f09/node-js.png 148w,\n/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/e4a3f/node-js.png 295w,\n/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/fcda8/node-js.png 590w,\n/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/efc66/node-js.png 885w,\n/tech-blog/static/a717eafa290bf333c4dd1c86076c5b9e/d9199/node-js.png 960w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>This is the part 5 of post <a href=\"https://alamgirqazi.github.io/tech-blog/intro-to-nodejs-part-4/\">Intro to Nodejs - part 4</a>.</p>\n<p>In this post, we will connect our Node.js App with an Ionic app. Most software development is done like this: Different teams works on different parts of the application. For e.g There will be a back-end team which will only focus building backends. Their focus will solely be on Node.js (or whatever language they use), Database (MongoDB or anyother). Same way, there will be different teams for Front-end Web whether its in React.js, Angular or any other framework. Again, different team for Mobile which can be hybrid or native.</p>\n<p>In first 4 posts, we were only concerned with back-end. Now we will see some front-end and see how the whole picture fits. We will use Ionic app but later we will see how easily we can reuse functionalities with our Web app if its in Angular.</p>\n<p>so lets start.</p>\n<p>first, lets create an ionic application from scratch.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">ionic start booky-ionic</code></pre></div>\n<p>Since we are going to be creating an API for books, I’m naming our project <code class=\"language-text\">Booky</code>. <code class=\"language-text\">Booky-ionic</code> will be our ionic code. aur node.js project could have the name Booky-node or whatever. It’s upto you.</p>\n<p>Usually its preferable we use different repositories for Ionic apps, front-end app and backend apps. Different repositories help us manage them more easily.</p>\n<p>So in our case, we will have 2 repositories. In case, we build an Angular web app, we might need a third named <code class=\"language-text\">Booky-angular</code> but we’ll see when we get there.</p>\n<p>Okay so we used a starter with side-menu by default.</p>\n<p>Lets clean things up a bit. I’m deleting lists folder because I don’t need it. I also have to remove the link from <code class=\"language-text\">app-routing.module.ts</code></p>\n<p>First thing, we need to create a login page.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">ionic g page login</code></pre></div>\n<p>lets also go ahead a create a register page.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">ionic g page register</code></pre></div>\n<p>All set. lets add some html code in login page.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&lt;ion-header>\n  &lt;ion-toolbar color=\"primary\">\n    &lt;ion-title class=\"ion-text-center\">Booky - Login&lt;/ion-title>\n  &lt;/ion-toolbar>\n&lt;/ion-header>\n\n&lt;ion-content color=\"\">\n  &lt;form>\n    &lt;ion-grid>\n      &lt;ion-row color=\"justify-content-center\">\n        &lt;ion-col class=\"ion-align-self-center\" size-md=\"6\" size-lg=\"5\" size-xs=\"12\">\n\n          &lt;div class=\"ion-padding\">\n\n            &lt;ion-item>\n              &lt;ion-input name=\"email\" type=\"email\" placeholder=\"your@email.com\">&lt;/ion-input>\n            &lt;/ion-item>\n            &lt;ion-item>\n              &lt;ion-input name=\"password\" type=\"password\" placeholder=\"Password\">&lt;/ion-input>\n            &lt;/ion-item>\n          &lt;/div>\n          &lt;div class=\"ion-padding\">\n            &lt;ion-button size=\"large\" color=\"primary\" type=\"submit\" expand=\"block\">Login&lt;/ion-button>\n          &lt;/div>\n        &lt;/ion-col>\n      &lt;/ion-row>\n    &lt;/ion-grid>\n  &lt;/form>\n&lt;/ion-content></code></pre></div>\n<p>We just added simple HTML for now. no forms etc just yet.</p>\n<p>This is how it looks</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/671006d58cc7cb4f69b972057658f1d0/fc1a1/bookylogin.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 466px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 147.2972972972973%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAYAAACqhkzFAAAACXBIWXMAABJ0AAASdAHeZh94AAACb0lEQVRIx+2VS2sUQRDH90N48SISUfHmxZuIF29ePPkNxIOgBPUgePEBisYHwYuJ+QYSMDESyINVQUTwAZoIHjxtYGd2xc3OTPd0ddffqt5dWNzN6+BBSLM/qru659+1VTVMhYjgvUeWZVhbW0O9Xkee5yjLMvp0boxBu92GDwGNRgO1Wg2tVitafaYoirjWM5U0TdFsNpE2mkjShgimqCcpkqQR6a2jr29fz6ey1ueVJEmirahqlsnt5TqC4K3SApkWnEB9c/VHumedbUtUWYysRyV4wnpeYnyecHeGcH+WcE/sgzmKvodzHR6/6u4JYy8Jt6YJz987gB2cI2jqFBEsUf9V4Nh1j5FR4PAVxoFRxtFrjDOPGCdvM47fYJweYxy6zDgoHLnK2HsBODdJAAyMdTHnSoWcQzsr8HbVoboS8OZ7h+pqwOJXj+VvJPhIdaXD61XCkux9+VmCSiNCfYKlCBpTyE1BkBt9LlMjcyt4bD4IhXSAc32CutCyEwXYkiTaHHlhIqXkxgcG+UG83K/7ZiPBID1WFBa/W1L13IA1voAoOAz5xSJsKMghdP+279Jb8xA6/qGCmlArOcytx9xnxouPjJm/mO2ff2JMf2C8+yGSYUgOrQh6Z1BrkrRFwL6LjP2XOFptoRM3GafudFpJfSNi95xnnB3XSF3M9UCEpZV3tSBMLVs8XTCYWFBrMbloMbVk8UxQ30TX92TeSNTS1GGTKndyuLPhNiuKl5JqVQfbg4e2zpZVDt0ImXlbxLberuBWY1dwV/C/EdSP/T95U3YyNhTsOXvf1u2iAtbaQUGdqKhGuhNUrCekqNYf3terQTlVc5AAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"booky login\"\n        title=\"\"\n        src=\"/tech-blog/static/671006d58cc7cb4f69b972057658f1d0/fc1a1/bookylogin.png\"\n        srcset=\"/tech-blog/static/671006d58cc7cb4f69b972057658f1d0/12f09/bookylogin.png 148w,\n/tech-blog/static/671006d58cc7cb4f69b972057658f1d0/e4a3f/bookylogin.png 295w,\n/tech-blog/static/671006d58cc7cb4f69b972057658f1d0/fc1a1/bookylogin.png 466w\"\n        sizes=\"(max-width: 466px) 100vw, 466px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>Looks neat.</p>\n<p>lets add Angular Reactive Forms.</p>\n<p><code class=\"language-text\">login.page.ts</code></p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { Component, OnInit } from '@angular/core';\nimport { FormBuilder, Validators } from '@angular/forms';\n\nimport { FormGroup } from '@angular/forms';\n\n@Component({\n  selector: 'app-login',\n  templateUrl: './login.page.html',\n  styleUrls: ['./login.page.scss']\n})\nexport class LoginPage implements OnInit {\n  constructor(private formBuilder: FormBuilder) {}\n  loginForm: FormGroup;\n\n  ngOnInit() {\n    this.formInitializer();\n  }\n\n  formInitializer() {\n    this.loginForm = this.formBuilder.group({\n      email: [null, [Validators.required, Validators.email]],\n      password: [null, [Validators.required]]\n    });\n  }\n}</code></pre></div>\n<p>remember, we have to add ReactiveFormsModule import in <code class=\"language-text\">login.module.ts</code></p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">@NgModule({\n  imports: [\n    CommonModule,\n    FormsModule,\n    ReactiveFormsModule,\n    IonicModule,\n    LoginPageRoutingModule\n  ],\n  declarations: [LoginPage]\n})</code></pre></div>\n<p>Okay, that’s good. Now we need to add the form controls into HTML of <code class=\"language-text\">login.page.ts</code></p>\n<p>Here’s after adding FormControlNames and FormGroup</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&lt;ion-content color=\"\">\n  &lt;form [formGroup]=\"loginForm\">\n    &lt;ion-grid>\n      &lt;ion-row color=\"justify-content-center\">\n        &lt;ion-col class=\"ion-align-self-center\" size-md=\"6\" size-lg=\"5\" size-xs=\"12\">\n\n          &lt;div class=\"ion-padding\">\n\n            &lt;ion-item>\n              &lt;ion-input name=\"email\" formControlName=\"email\" type=\"email\" placeholder=\"your@email.com\">&lt;/ion-input>\n            &lt;/ion-item>\n            &lt;ion-item>\n              &lt;ion-input name=\"password\" formControlName=\"password\" type=\"password\" placeholder=\"Password\">&lt;/ion-input>\n            &lt;/ion-item>\n          &lt;/div>\n          &lt;div class=\"ion-padding\">\n            &lt;ion-button size=\"large\" [disabled]=\"loginForm.invalid\" (click)=\"save()\" color=\"primary\" type=\"submit\" expand=\"block\">Login\n            &lt;/ion-button>\n          &lt;/div>\n        &lt;/ion-col>\n      &lt;/ion-row>\n    &lt;/ion-grid>\n  &lt;/form>\n&lt;/ion-content></code></pre></div>\n<p>We also added a save() function on click. The click will only trigger if the form is valid.</p>\n<p>Lets write some logic</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">  save() {\n    const loginData = this.loginForm.value;\n    console.log('loginData', loginData);\n  }</code></pre></div>\n<p>What we need to do now is send a request to Booky-Node (our backend). We need to send a request to <a href=\"localhost:3000/users/login\">localhost:3000/users/login</a>.</p>\n<p>We need to do an API request.</p>\n<p>So for API requests, we need services.</p>\n<p>Lets create a <code class=\"language-text\">User</code> service.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">ionic g service user</code></pre></div>\n<p>Awesome. Two files will be created for us.</p>\n<p>However, to make services more manageable, we will move them in proper folder structure.</p>\n<p>Here’s what I do</p>\n<p>create an <code class=\"language-text\">sdk</code> folder inside <code class=\"language-text\">app</code> directory.</p>\n<p>create a file named <code class=\"language-text\">booky.config.ts</code></p>\n<p>create a folder named <code class=\"language-text\">core</code></p>\n<p>This will contain core services</p>\n<p>create a folder named <code class=\"language-text\">custom</code></p>\n<p>This will contain our custom services e.g User, Books etc</p>\n<p>This is what the folder structure looks like</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/770dd875d8e29c303b1fde790fbfd268/8f77f/folderstructure.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 346px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 168.24324324324326%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAACXBIWXMAABJ0AAASdAHeZh94AAAERElEQVRIx52W2W7bRhSG9QgtELRJI1sSJS7Dfd9FarVkxXZipHFrt00KxLkskN70rkAv+9Z/z4wsWXJox+7FAYnh8ONZ/2FLt2Pk1RznP17h3cWvWKze4Oz8J7z7+T3csISiB9DM8NHWUnQfphujHB9hePIaUT5CWc9R1DPodoSB5kBmrrCB5m7vm9c8tCTVxkAx0dNdsN+vERMoH07R7mlkKg4kRleGwz5Dd6A3WoeMP++rFlp9AnJjtovT9xMEcQLHcuC6Hix+dVxEvg/DsMXLPdnYM76maCaYbkFSdoCKaePtxyXSLEPgOAgJ4rtrWB4HsG1HeNIEHKgmVGbeAgfkKnN8OJdDDNIIsheg3dUoDH0dssTE/QawB6T1PiOnKBoB5EmX6IGkO5iUKVZFAcn2IOt2ozdNa33NQp/2b4FdnnACrswYn8evoFQZ9DzBARVFvPQQkHtIMHnXw57M0JE9vF7a+PyphOmVVOkx/ChHhz62gW2ATdfOpsoCSAuS4mI09nF5NYbhZojzChb1565X94W8jkK/BYrSy9QiyyGKD8cIvAL1ZIFqcoTJfIXJ0QrlaE4fNRs/8IWH69JbCNIKw+kx1CAACyJRrJ5iCBC3xirzojALA2O3KBxIlYrLKerFGZTIh0z9d9BV9/J3N3d7Vb4LlJlDzWnjxfFfsIbnKMsaTpDhUNK+yFtTHrv7ITPy0BbQKYmD56ew/EQURaZ24glfv9w8y92b9f5t2xhQSRxUK8S/ywhvyhxhPqGqL5BkNToSvXBja7B5azu55VPXYqSHvE3soIBBwG8u/oG8vEQ0qhDO5/DrMcLpDMnxQlxNPxf7t+aksKMSbjECsxK0hDBaEbjQMidDZ3wFls9oA22qKI9lBTuj+5rfD8XezTube+bE0ClNKhdYnjs++LpGeZz+hvzD3yiSFNV4iSAs0D6U0e4oOCR95Nbd6iK7sXVBOlS829HjAkmJdVmEkTuCHWY0ehOEyVBUWrfDncLcX+m90WvT10LVQ6YGSKoJimqKhPKyhqbbmX4C0ESqynht9OGmIwJOBDAnsEtePgnYHdCCpJKwDsHKE9huSOJA3qVD2NSPquE2CsP9QC6w3T6+L9/i27M/SfYDOvXmiLJKbN7q4s74fR3YG+BleoLvFtfwXB8ZnXyj6VLkUKGmf1rIN8AfOHD5CWmcIqPcpcU6bFUA/0fIL4pzPDv5A0nI/yZmIn/P230KWdtT7ieE/IpC/gjbdOCEOfy4oN8RGi/qw68VphH4PD3Fs6NrREGMtOSHfon58lSoN/f2oTzeaRsuPQYuzC58w0Q1W4lJ4TnkU/KyI2918XEh32w6ZgyuHdAPU019WIuQTTcSav4Q7F7gLzTckRORh0v6A5uJP7CaWsfbOU4fBeyIQ8rA0VRDkvIpobEjD4OkFFCu3E8cPX4uGxgVGsIoJFAlQg4JyK+W93jgfxIkCKu35oFVAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"folderstructure\"\n        title=\"\"\n        src=\"/tech-blog/static/770dd875d8e29c303b1fde790fbfd268/8f77f/folderstructure.png\"\n        srcset=\"/tech-blog/static/770dd875d8e29c303b1fde790fbfd268/12f09/folderstructure.png 148w,\n/tech-blog/static/770dd875d8e29c303b1fde790fbfd268/e4a3f/folderstructure.png 295w,\n/tech-blog/static/770dd875d8e29c303b1fde790fbfd268/8f77f/folderstructure.png 346w\"\n        sizes=\"(max-width: 346px) 100vw, 346px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>Our config file is empty. Lets add some boilerplate code</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">export class BookyConfig {\n  private static path = 'http://localhost:3000';\n\n  public static getPath(): string {\n    return BookyConfig.path;\n  }\n}</code></pre></div>\n<p>The purpose of this is that whenever our backend URL changes, for e.g our backend is live at <code class=\"language-text\">api.booky.com</code>, then we only need to make a change in one file and all URLs will be updated.</p>\n<p>Ok, so lets move on.</p>\n<p>we created a user service but its in outer app folder. There was also a .spec file. I’ll just delete the .spec file and move the <code class=\"language-text\">user.service.ts</code> file to <code class=\"language-text\">sdk -> custom -> user.service.ts</code></p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/ba70619eb2b751b5668ade9797e900c6/5fad2/userservice.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 310px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 52.70270270270271%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABxUlEQVQoz41S2U7bUBT0Y/+hQon3u/l6X+I4iR2CItOCiAitBGpBqB/QD6lQ/3g4NotEqwgeRj6+92jO3Dlj8CABD1Kc7m+Q1h1kU0FWJaYWh+nKD2Fqc3hhDE/HMDwewmUaXb9DlFfwixRuFONo6j81O+J9QuqxhYYjQhhTOtBhgiO1gHv9gDhfoG46FHWLic3fJX25m9rDV8GwPQWPD+wZxHIPHubQUQkuE0xMBtORH366RVyGRQWLCqziCH+/ziDiDGxeQq8bhF0DiylMLDYqOYTh3iOb3MFDpjJwnUPIDFfbFm1H6tIKKifytISvUrAggy/TER4pfws6EwlEWBBKGDptkBRLOLLG9ZnE77sIy+NL7L/d4qS/xMXVT+wIZ7sbnJ5/h4rnCJK3EOEMTdujXvW0ZZriiwhWOMdkewueDJNyqGw2+jmok6RUJuX47/Dof7AQHsXP1xkMk4w0TQefVYlPPx5gVw2CtoLeLEYf1WKGeLtC+mWNYFkf9jAmwih5yqEnydDNPUS5QUQKJS1JUNhtFmAYOOaM6mGLh8P9HBtGZMOzi19/0F7cYX18Qt6do9v0sP3guVG+qvm3fiV0xTjwEajxU3ITrvhsAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"userservice\"\n        title=\"\"\n        src=\"/tech-blog/static/ba70619eb2b751b5668ade9797e900c6/5fad2/userservice.png\"\n        srcset=\"/tech-blog/static/ba70619eb2b751b5668ade9797e900c6/12f09/userservice.png 148w,\n/tech-blog/static/ba70619eb2b751b5668ade9797e900c6/e4a3f/userservice.png 295w,\n/tech-blog/static/ba70619eb2b751b5668ade9797e900c6/5fad2/userservice.png 310w\"\n        sizes=\"(max-width: 310px) 100vw, 310px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>This also keeps the services organized.</p>\n<p>Okay, so for user, we need to create a service method for login</p>\n<p>Here’s how <code class=\"language-text\">user.service.ts</code> file looks</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { HttpClient, HttpHeaders } from '@angular/common/http';\n\nimport { BookyConfig } from '../booky.config';\nimport { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class UserService {\n  constructor(private http: HttpClient) {}\n\n  public userLogin(credentials: object): Observable&lt;any> {\n\n    // this url will be http://localhost:3000/users/login\n    const url = BookyConfig.getPath() + '/users/login';\n\n    return this.http.post(url, credentials);\n  }\n}</code></pre></div>\n<p>After this, I need to import <code class=\"language-text\">HttpClientModule</code> in imports of app.module.ts because we are using it in service.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { HttpClientModule } from '@angular/common/http';</code></pre></div>\n<p>Lets go to login.page.ts and write the <code class=\"language-text\">.subscribe</code> method</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">save() {\n    const loginData = this.loginForm.value;\n    console.log('loginData', loginData);\n    // we need to send this data to our node.js server\n\n    this.userService.userLogin(loginData).subscribe(\n      data => {\n        console.log('got response from server', data);\n        this.loading = false;\n      },\n      error => {\n        this.loading = false;\n        console.log('error', error);\n      }\n    );\n  }</code></pre></div>\n<p>lets go to <a href=\"localhost:8100/login\">localhost:8100/login</a> and see if it works</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/6c99d/boom.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 60.13513513513513%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABJ0AAASdAHeZh94AAABkElEQVQoz42Sy07DMBBF8/Us2ReJFT/Ahh2VuoBfQFVVEIg2SZukednx25exE0qLkOhIRx5b4+t5OGGM4VLSfRvZlT0+8wb5/oC+785iEikl/kMpCT5IzB4Vrh8UbuYGV/cWz0sNeIlB/MQmWmtcgiKMEoAlJrPG0GPqLC4JB/8hlYa3CosXi9nc4+7J4Xbhsa00nAkx+hh7kWDAaEUCFi8bi1VqsUwdOh6y+iV4cckUTA3DqTn3R8kylCRVbKyICPKJYRjXyQ/n8RL17ZtxEOJsgMnHJkW+26EsK1oL1IcDWNehD/R99Bmt4bxpmiN1XaNt2/G7hLiJ5H29wtvrGqwoUGUZyjRDvd2ipUf6NIXMcsimg6JgQ+KWczjK2JGQo33AMA7FBH0AyjDbbLAlrLOQTKHJKcOyAKcHeFVhoMyCLygjGS4HQWqTd44mb8eVcM7De4+krA6xXEeCRhh0BYOmkuzAaQZ+JNjkRwF/PpxTSxjrY6+MsfSnHBQX4G0DEcqhJkeBqDdm4KdZH/e/+AI2RKAQl8WpFQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"boom\"\n        title=\"\"\n        src=\"/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/fcda8/boom.png\"\n        srcset=\"/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/12f09/boom.png 148w,\n/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/e4a3f/boom.png 295w,\n/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/fcda8/boom.png 590w,\n/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/efc66/boom.png 885w,\n/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/c83ae/boom.png 1180w,\n/tech-blog/static/724e1ebaf94f79f266adf93578c09b44/6c99d/boom.png 1447w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>BOOM ! We successfully connected our ionic app with our backend. Hurray !! Lets also add Full stack developer to our CV while we’re at it :)</p>\n<p>lets get back.</p>\n<p>we got 401 unauthorized error. We can also see our custom message ‘Please signup first’ in the console.</p>\n<p>Lets try it with a user that already exists.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/29114/success.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 41.21621621621622%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABBElEQVQoz32RW2vDMAyF8/9/0va8pz0MVggMSttRSJe0aWo7ji+yfSa7l22Q7OFDR7IkDnKltcYSxmjUnyNe6iurjeC6YqbFmcp7jzkcQ+RR7x1e14S3HfDRhFJzCzOZyjmHOSyTosP2y+HpPeJ5lbDrCCnkN4+lubJwyWEgh14SNm1iYtG55tw/Dr2nv86sfWCMZZcEIBWytnbe2WPhoe1w6s84nQdchCiHHcexRMVRSMVRQ6qx5Hqafvj1GUopDMOAarteozseMfQXqLaF73s4biBuCLyAMjm/6xueFwZ2FG9oKTFxvTo0DYSQiBRBxiCy/Uh0bcw6M6c5Ju67gxD4KgnfqSlsByFx4fwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"success\"\n        title=\"\"\n        src=\"/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/fcda8/success.png\"\n        srcset=\"/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/12f09/success.png 148w,\n/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/e4a3f/success.png 295w,\n/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/fcda8/success.png 590w,\n/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/efc66/success.png 885w,\n/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/c83ae/success.png 1180w,\n/tech-blog/static/8f5945b92871ed8b7611a5273638e9e0/29114/success.png 1920w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>Awesome. We get success message. After login, we’re not doing anything right now. we should however take it to a different page. something like /books where we can see our own books but right now we’ll just navigate it home page.</p>\n<p>we need to do two things here which we’re not doing right now. 1. we need to save the JWT token from the server. That’s how we will know which user it is. 2. We are not showing any loading screen for now. It’s all happening very quick. We should add a loader.</p>\n<p>We’ll come back to this later.</p>\n<p>Lets just write that navigate method and we’ll move to register page.</p>\n<p>add these</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { Router } from '@angular/router';\n\n\nconstructor ( private router: Router)\n\n this.userService.userLogin(loginData).subscribe(\n      data => {\n        console.log('got response from server', data);\n        this.loading = false;\n        this.router.navigateByUrl('/home');\n      },\n      error => {\n        this.loading = false;\n        console.log('error', error);\n      }\n    );</code></pre></div>\n<p>Ok. so far so good. We need to provide users a way to signup from the ionic app. Lets add code to that <code class=\"language-text\">register</code> page we created.</p>\n<p>Here is register.page.html</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&lt;ion-header>\n  &lt;ion-toolbar color=\"primary\">\n    &lt;ion-title class=\"ion-text-center\">Booky - Register&lt;/ion-title>\n  &lt;/ion-toolbar>\n&lt;/ion-header>\n\n&lt;ion-content color=\"\">\n  &lt;form [formGroup]=\"registerForm\">\n    &lt;ion-grid>\n      &lt;ion-row color=\"justify-content-center\">\n        &lt;ion-col class=\"ion-align-self-center\" size-md=\"6\" size-lg=\"5\" size-xs=\"12\">\n          &lt;div class=\"ion-text-center\">\n            &lt;h3>Create your account!&lt;/h3>\n          &lt;/div>\n          &lt;div class=\"ion-padding\">\n            &lt;ion-item>\n              &lt;ion-input name=\"name\" formControlName=\"name\" type=\"text\" placeholder=\"Name\">&lt;/ion-input>\n            &lt;/ion-item>\n            &lt;ion-item>\n              &lt;ion-input name=\"email\" formControlName=\"email\" type=\"email\" placeholder=\"your@email.com\">&lt;/ion-input>\n            &lt;/ion-item>\n            &lt;ion-item>\n              &lt;ion-input name=\"password\" formControlName=\"password\" type=\"password\" placeholder=\"Password\">&lt;/ion-input>\n            &lt;/ion-item>\n            &lt;ion-item>\n              &lt;ion-input name=\"password\" formControlName=\"confirm_password\" type=\"password\" placeholder=\"Password\">\n              &lt;/ion-input>\n            &lt;/ion-item>\n          &lt;/div>\n          &lt;div class=\"ion-padding\">\n            &lt;ion-button size=\"large\" [disabled]=\"registerForm.invalid\" (click)=\"save()\" color=\"primary\" type=\"submit\"\n              expand=\"block\">Register\n            &lt;/ion-button>\n          &lt;/div>\n        &lt;/ion-col>\n      &lt;/ion-row>\n    &lt;/ion-grid>\n  &lt;/form>\n&lt;/ion-content></code></pre></div>\n<p>Here is what the view looks like</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/32c225c31995f9196cf65c401247a0ad/cc097/register.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 394px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 157.43243243243242%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAfCAYAAADnTu3OAAAACXBIWXMAABJ0AAASdAHeZh94AAACdUlEQVRIx+2Vu2/TUBTG82/AiISY2UHiT0AMvIRgAMQCC4KJDdQFBgopD6l04TGiCmgSUrEgUSQEapMSlLlN2rRJQ+z6bd97Pu6x48pJ3SQtXZC40ufX+e7PR+deH2dczwekg7FpHycfSpx/InBuQuJsVuLypMS1KYmLzyWuTEa6+kLiwlMVVx72sZ/nvf3mAXCRcV0G2rj0zMfBG8CR24TDtwiHbhKO35M4kyWcGCMcu0s4ra5PjROO3oni7GP/gevARLEL9FSGvmdjruri3Q+B3EKAmfkAhZJEvgy8nwdyJcLMAkLxfWERyKs4+9jP86rLDkSggL7vw7ZtRVeZhoPCo3Q16Bs1WFoDgd2GZ7bgGk11bmKzXQcCo8cP6cFxEkCupZAIJZXHMG3UVxporDXRbLWx3trAejPSSmMNpuWEvkBQOMdxPbhuAshnHkIISCkxyiCirWvPSwEySNO0bgmiCSx+3q84FkNTgRzkDPmaFQRBqBiahCRfNhBomiY6nQ50XYdhGNuyTdNAYJwZZzoMNBTI6XNWo2a2qwzj2v0VUPAq65tqpXVVSyvcZ1LSUNFOwO1Ddr+EQdphlUXgY7UDlJcIlVpXdcLPWqRKin6peHmZoKlyB0Hi07N4AaSPTxXCgxyQnQUeF4FHSq/ngFdKL78Ab74CU5+B8WIUZ9995a+uUvgt20kgCR+LSxLT37njCNVJIhVKAh9L0ZmVV7EP3Rj72F//rWop+prDVg1J9ohS1O/BoEUh7G7QoOYw6kYeeR/2t6RR2td/4L8K3Ndts9fRA3QcJ3zAHVsImfqXG6YeIN8w1LKsPStOKsOH+Le5H/oDBvNOiUU8uIsAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"register\"\n        title=\"\"\n        src=\"/tech-blog/static/32c225c31995f9196cf65c401247a0ad/cc097/register.png\"\n        srcset=\"/tech-blog/static/32c225c31995f9196cf65c401247a0ad/12f09/register.png 148w,\n/tech-blog/static/32c225c31995f9196cf65c401247a0ad/e4a3f/register.png 295w,\n/tech-blog/static/32c225c31995f9196cf65c401247a0ad/cc097/register.png 394w\"\n        sizes=\"(max-width: 394px) 100vw, 394px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>lets write some typescript code</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { AbstractControl, FormBuilder, Validators } from '@angular/forms';\nimport { Component, OnInit } from '@angular/core';\n\nimport { FormGroup } from '@angular/forms';\nimport { Subscription } from 'rxjs';\n\n@Component({\n  selector: 'app-register',\n  templateUrl: './register.page.html',\n  styleUrls: ['./register.page.scss']\n})\nexport class RegisterPage implements OnInit {\n  constructor(private formBuilder: FormBuilder) {}\n  registerForm: FormGroup;\n\n  ngOnInit() {\n    this.formInitializer();\n  }\n\n  formInitializer() {\n    this.registerForm = this.formBuilder.group({\n      name: ['', [Validators.required]],\n      email: ['', [Validators.required, Validators.email]],\n      password: ['', [Validators.required, Validators.minLength(5)]],\n      confirm_password: [\n        '',\n        [\n          Validators.required,\n          Validators.minLength(5),\n          this.matchOtherValidator('password')\n        ]\n      ]\n    });\n  }\n\n  matchOtherValidator(otherControlName: string) {\n    return (control: AbstractControl): { [key: string]: any } => {\n      const otherControl: AbstractControl = control.root.get(otherControlName);\n\n      if (otherControl) {\n        const subscription: Subscription = otherControl.valueChanges.subscribe(\n          () => {\n            control.updateValueAndValidity();\n            subscription.unsubscribe();\n          }\n        );\n      }\n\n      return otherControl &amp;&amp; control.value !== otherControl.value\n        ? { match: true }\n        : null;\n    };\n  }\n}</code></pre></div>\n<p>A couple of new things were added to this. I used a custom validator. Don’t worry I didn’t wrote it myself :) I just copy / pasted from Stackoverflow :) Full Stackoverflow developer :D</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/28c044f9707038355c5a289155877df2/52211/fullstack.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 525px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 84.45945945945947%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAADuElEQVQ4y2P4Twj8+/cPlxQDhHr8+PGjR4+A5I0bNx48eHDz5s0fP34AxX///g3XDyfhAKr54cOHFy5cAOo5ceLE7du3gYyfP3/+/fv38uXLR44cAXKxOoEBqOLXr19APadPn75+/frBgweBJETp9+/fjx49euzYsZOnTp49e/bSxYunT5+6cvXq8ePHz5079+zZM5DNQP137945c+bM5StXgFYBnQ03+8uXL58+A8GXR0+fPX356vmLF29fv/r8+dOH9+/evX3LsHr16jmz586aOWfqlGkTJ0ycM3f20mWLli5fvnDR0jVrN23ZuGHd6pVrV644vXPbjQO7zp04vmnX4fkLVy5csvrFy1cMAvwCnJycIiKiTEysQoL8GhoqWkqyKiICHGy8WjrWhuoqskJ8auKC+bZGYXoq+srqXILyDAxcDAzse/bsY/Byd81OCEvyc7QzVtfRU3K0tYhzNJsQ6WqiIGlo6uxkbmKspWqppRpjri8pKMTKzM3FxsPHycvJynVg/wGG/vrCCRkhc1PD68Pd1ZTElcUEIiy0KgNtzRQlLK3sy4tKgjzd7EwMFcWE5SWkuNh5QZq5+AW5Bfbv28/Qlh1RF+rYHuXdGOpmryWnIyFY6G5aE+SgIsxrZGJaX9tYW1IY5OEsxMOdHBIwp6+js7aqID5GXkxs3549DJneFuVelr2RPhOj/QKMVe311KZmRE7Lig6xt3RzdPT39k2ICHazNpcVl8yJCji+uP/Y2sXtFaXsDAyHDuxnyAmwKnYz6Qr1SLE1yvN3Wtpas6M5b0lJYqKDcXKov5OtnbGWtqW+jqqsXHF8eHd27Jy20pKcLE5mzgP79jHUJPvnuRsVuJg2RvotKk8v9nfsjHINtTbgYWIM8HD19/aRFZeVFpe0s3OKi4iY0lGzecnUGRMaUpPCb16/xuBibRxkrZbhbrq6Lr8zJUSah81OUUxMgI+ThdncxMTG2k5aXFZeVtHD18fQWNPNwyw80i010a2hNPje3esMRYnhfrZGC2tyVtZkmWsqCXFy2GjISwgLSglyuzna2dg46aiq6WtoqSurGOvpBPt65GUkxUSGzZ/Y/PXjW4YVnU2TsyJnZQamOhsyMDCwMDDI8bCxMjMD04GDhWFEdERkqH18pEtCuHNxesSK6T371y3euGjWnJ6mF48fMFw8vP/01lXHNy1fOXdaU2Nza1PzxM72rta2/rbmZQvmrtu4btHiOUuWzF68ZNbObWtvXzhz7fSJq6eOXTp+8POHdwCSYRfki/t2GwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"fullstack\"\n        title=\"\"\n        src=\"/tech-blog/static/28c044f9707038355c5a289155877df2/52211/fullstack.png\"\n        srcset=\"/tech-blog/static/28c044f9707038355c5a289155877df2/12f09/fullstack.png 148w,\n/tech-blog/static/28c044f9707038355c5a289155877df2/e4a3f/fullstack.png 295w,\n/tech-blog/static/28c044f9707038355c5a289155877df2/52211/fullstack.png 525w\"\n        sizes=\"(max-width: 525px) 100vw, 525px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>Okay, coming back to this</p>\n<p>Our scenario, which we often see in some apps is that you need to write password two times. and comparing both of them is not that straight-forward when it comes to making it work with the custom validations that we already use. Lets see it in action.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/tech-blog/static/2e079b4ae5a03850efa96f75cf0bc328/6c1e7/confirmpassword.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 413px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 150.67567567567568%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAACXBIWXMAABJ0AAASdAHeZh94AAACkklEQVRIx+2WO2/UQBDH82noEYhHQwvikQ4axOND0PGUqBCEIkUeFBESIjwk6BBCAqIIkSAoIiAQJArCJQdJ7pw739m79tmzf2Z27cSKck4OEBUr/T1jz+zPs97HXV8cd9DpxGiHEepNDa+pnHyFlVWFJU+h1lBYznyx9TwnU6OlEccxczro01EHQISxiRgHrhr03yQcuUE4fJ1wcohwdpRwfJBwaphwetjZYwOcw/GjnHfwGuHMSAo/0EgSBioL1Bh8GmHHOYP9Vwh7LhF2XXCdBHCIO/UPSEfCCYbv45zdFwl7LxN2njecl6LZUg5ohxxrLKxofKgQPi2kVnNVwuwC8P472Bp8rBj2WWznqmYtb5b1pZogDJUbslyU0qAkhmvGXnXQwOL8VyxVv8FfXYa3srgmeQbk+dIIWivEOVBrzYpgTIZkG3Hl7SC0CvmFooCrEImfpgQiWCXsK1WoUIBRFDPIoNFo2EAvjagE2Gq1Nu0gMbG5X1QXYGQ7e56HSqWCWq1mJTH3GUxXlQJ930e9Xkez2bSSBVsGLBmyAwbttk0otrLqtqwwzAI2cQuQVbcKZWiGA6s8XM1B8SlJQWmJOG5S6lKhfCveOryiWSGggszfRKogzhW4Ysb6TpGbOELIvB9NYKmVyXf3Rf301+Pie4Ebsi5WKCsfFGFm3mDwmcGtCYPRF86OTxncn3b24RuDsUmDEYm9NBh67p51kmzrxUVgGuHzosHtyRT3pgjjr8naR28Jj9+t2wfThLtZ7M4rwpMZ4lNmAzCfZZkx2aNFyduLSjbEibZYNr/TSoFmO2uvl52SJ22n/Qf+Q+Bfn+W/BIz/aGHr4mkj1eVnovi9y/WzwPxPjlj3+9y7BJZzfgE01gIxnKIG4gAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"confirmpassword\"\n        title=\"\"\n        src=\"/tech-blog/static/2e079b4ae5a03850efa96f75cf0bc328/6c1e7/confirmpassword.png\"\n        srcset=\"/tech-blog/static/2e079b4ae5a03850efa96f75cf0bc328/12f09/confirmpassword.png 148w,\n/tech-blog/static/2e079b4ae5a03850efa96f75cf0bc328/e4a3f/confirmpassword.png 295w,\n/tech-blog/static/2e079b4ae5a03850efa96f75cf0bc328/6c1e7/confirmpassword.png 413w\"\n        sizes=\"(max-width: 413px) 100vw, 413px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>It not enabling the register button and we can see the red line because the passwords I typed didnot match. We are able to handle it quite easily and gracefully in Angular.</p>\n<p>Right, we need to save() method and also add a register method in <code class=\"language-text\">user.service.ts</code></p>\n<p>Lets add this method</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">public userRegister(credentials: object): Observable&lt;any> {\n    const url = BookyConfig.getPath() + '/users/register';\n\n    return this.http.post(url, credentials);\n  }</code></pre></div>\n<p>Lets write that save method</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">save() {\n    this.loading = true;\n\n    this.userService.userRegister(this.registerForm.value).subscribe(\n      data => {\n        console.log('got response from server', data);\n        this.loading = false;\n        this.router.navigateByUrl('/home');\n      },\n      error => {\n        this.loading = false;\n        console.log('error', error);\n      }\n    );\n  }</code></pre></div>\n<p>Again once our register is succeessful, we need to navigate it to <code class=\"language-text\">/home</code> page or eventually <code class=\"language-text\">/books</code> page.</p>\n<p>We covered a lot in this post. Few things we will cover in the next part are</p>\n<ol>\n<li>Showing proper Error Messages to user and success message</li>\n<li>Showing some loader</li>\n<li>saving JWT Token</li>\n<li>Complete Books API integration</li>\n</ol>\n<p>Here’s <a href=\"https://github.com/alamgirqazi/booky-ionic\">link</a> to the ionic app code.</p>","frontmatter":{"title":"A very basic introduction to Node.js - Part 5","date":"December 02, 2019"}}},"pageContext":{"slug":"/intro-to-nodejs-part-5/","previous":{"fields":{"slug":"/intro-to-nodejs-part-4/"},"frontmatter":{"title":"A very basic introduction to Node.js - Part 4"}},"next":{"fields":{"slug":"/intro-to-nodejs-part-6/"},"frontmatter":{"title":"A very basic introduction to Node.js - Part 6"}}}},"staticQueryHashes":[]}