Wednesday, 5 December 2018

Passing data between the nested component in Angular

Background

In the last post, we saw how we can create nested components in Angular -
We also saw a few other angular things - links creating a new App, using Angular CLI, understanding project structure etc. All the links are in the related links section at the bottom. In this post, I will show you how to pass data from parent component to child component and listen for data to be passed from child to parent. 

I am going to continue using previous code example that we have built so far. So if you need additional guidance before we start with this code, look up the previous post that talks about building nested components

Passing data between the nested component in Angular

At this point, you should have a parent component called NewEmployeeComponent and a child component called SubempComponent. Child component just has a static HTML saying that subcomponent works. And it gets rendered as part of the parent component. All of this works and we saw it in the last post. If you do have a question till here I would recommend to go back and read my previous post -
Now let's add some input and output properties in the child component. Your child component code should look like below -

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-subemp',
  templateUrl: './subemp.component.html',
  styleUrls: ['./subemp.component.css']
})
export class SubempComponent implements OnInit {


  @Input()
  department:string;


  @Input()
  designation:string;


  @Output()
  joined:EventEmitter<string>;


  constructor() {
    this.joined = new EventEmitter();
  }


  ngOnInit() {
    console.log("SubempComponent initialized");
  }


  onButtonClick = function(event) {
    console.log("Button clicked. Emitting now!")
    this.joined.emit("Joined department " + this.department + " with designation " + this.designation);
  }


}

Notice here that department and designation are two parameters which are input and are of type string. So we would expect the parent component to send it to this child component. Next, we have an output parameter called joined which is an EventEmitter. Parent component which creates this child component can catch and handle this output and we will see how in a moment. Finally, we have a function onButtonClick that actually emits a string saying that the button was clicked with the particular designation and department. We will now see when this function will get called. But essentially once this function is called we emit the string which the parent component can intercept and handle.

Now let's see child components HTML code -

<h1>This is sub components heading</h1>
<p>
  Yay! subemp works!
  Department : {{department}} <br/>
  Designation : {{designation}} <br/>


  <button (click)="onButtonClick($event)">Click to join!</button>
</p>


From the previous version of the code, I have just added lines to print department, designation and a button on click of which we call function onButtonClick which we just saw above. This function will, in turn, emit the event that will be caught and handled in the parent. We will now see changes in parent component and once done we will execute our code and see it in action.


Make changes to parent component typescript file so that it looks like below -

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-new-employee',
  templateUrl: './new-employee.component.html',
  styleUrls: ['./new-employee.component.css']
})
export class NewEmployeeComponent implements OnInit {

  name: string;
  age: number;

  constructor() { }

  ngOnInit() {
    this.name = "Aniket";
    this.age = 27;
  }

  childClickedButton = function(event) {
    console.log("Child component clicked. event : " + event);
  }

}



Notice that the only new change here is a new function called childClickedButton that we will use to catch and handle the output of child component we say above.

Now make changes to the parent's HTML file so that it looks like below -

<h1>Welcome to the Employee portal</h1>

<h3>Name : {{name}}</h3>

<h3>Age : {{age}}</h3>

<app-subemp

    [department]="'IT'"
    [designation]="'Software developer'"
    (joined)="childClickedButton($event)"
></app-subemp>

</pre>



We have changed some things in the way we add child component in the HTML file. This is how we send input to the child component and handle the output. It's called data binding. So we are essentially sending department and designation as inputs to the child component. We saw these as @input() variables in child component. Similarly, we are now catching joined which was a output and calling our user defined function childClickedButton function. So the string emitted by the child on the actual button clicked will be sent as the event to this function.

Now let's see this in action. Run the app with command -

  • ng serve -o
You should see the following screen -




Make sure you go to the correct URL path to render the components. Now you can click the "click to join" button in the parent and see the console logs. You should see the following -






You can see the button click event happened which emitted the event from the child. Parent captured it and printed another console log. That's how you can configure inputs and outputs for nested angular components and pass data.


Related Links


  • Angular Hello World example
  • Understanding angular application folder structure
  • Routing and navigation in Angular
  • Tuesday, 27 November 2018

    Building nested components in Angular

    Background

    So far in learning Angular, we have seen following posts -
    1. Angular Hello World example
    2. Understanding angular application folder structure
    3. Routing and navigation in Angular
    This post is the continuation of the same series. If you are directly landing on this post please do take a look at above posts to understand the basics. This post assumes you have an Angular project set up with a component and it's navigation.

    In this post, we will try to add a new component that will be used in our existing component.


    Building nested components in Angular

    In the last post, we created a new component new-employee and set up navigation for it. Following is the final output from it.



    In this post, we will create a new component and add it inside our new-employee component. So let's create a new component. To do that execute the following command -

    • ng g c employee/subemp
    This is shorthand for -
    • ng generate component employee/subemp
    Your output should look like -


    athakur@athakur-Inspiron-7560:~/Documents/per_code/angulardemo$ ng g c employee/subemp
    CREATE src/app/employee/subemp/subemp.component.css (0 bytes)
    CREATE src/app/employee/subemp/subemp.component.html (25 bytes)
    CREATE src/app/employee/subemp/subemp.component.spec.ts (628 bytes)
    CREATE src/app/employee/subemp/subemp.component.ts (269 bytes)
    UPDATE src/app/app.module.ts (597 bytes)
    

    Notice the new files created and the root module updated with import and declaration of the new component. This is exactly the same steps we did for our earlier component. If you recall in the last post we generated the new-employee component similar way -
    • ng generate component employee/new-employee 
    The directory structure should look like below now -




    Now let's start adding code. First, go to subemp.component.ts and add/edit code so that it looks like below -

    import { Component, OnInit, Input } from '@angular/core';
    @Component({
      selector: 'app-subemp',
      templateUrl: './subemp.component.html',
      styleUrls: ['./subemp.component.css']
    })
    export class SubempComponent implements OnInit {
      constructor() { }
      ngOnInit() {
        console.log("SubempComponent initialized");
      }
    }
    


    This is a very basic boilerplate code.  Notice that this components HTML is in file './subemp.component.html' and similarly, CSS is in './subemp.component.css'. Also, note that this components selector is called 'app-subemp'. So that's the tag we will use in the parent's HTML template file.

    Let's make changes to the child's HTML template now. Go to './subemp.component.html'  and add following code.

    <h1>This is sub components heading</h1>
    <p>
      Yay! subemp works!
    </p>
    
    

    There are no changes needed in the CSS file. But if you are defining custom CSS then you can add it in 
    './subemp.component.html'. Now finally let's add the child component in the parent component. So go to parent components HTML file - new-employee.component.html and make sure it looks like below -


    <h1>Welcome to the Employee portal</h1>
    <h3>Name : {{name}}</h3>
    <h3>Age : {{age}}</h3>
    <app-subemp></app-subemp>
    


    The only new thing that we have added here is an <app-subemp></app-subemp> tag that we say was the selector of the child component. Now finally run -
    • ng serve -o
    to build and run your angular app and you should see below output in the browser.




    You can see how the sub-component renders inside the parent component.

    Also, note that we added this route in the last post. So we are just navigating to this route and seeing the changes.

    If you are wondering how it figures out the app-subemp tag then you can look at the app.module.ts file which is the angular root module file. Here we have imported this new component and added in the declaration section. This automatically happens when you use angular cli to generate a new component like we did above with command -

    • ng generate component <component_name>
    In the subsequent posts, we will see some more angular topics so stay tuned.



    Related Links

    Sunday, 25 November 2018

    Routing and navigation in Angular

    Background

    This post is in continuation of previous two posts on Angular -
    In this post, we will see how we can set up routing and navigation in Angular. If you are new to Angular please read the Hello World go through the posts above first. This post assumes you have a base project already setup as we did in the last post.

    Our current angular project looks something like below -




    Routing and navigation in Angular

    Before we start adding routing and navigation let's add a new component first and then we would add routing to that component. To generate a new component we can use the following command -
    • ng generate component <component-name>
    In our case, we will create a new component called new-employee and we will put it under a directory called employee. So use the following command -
    • ng generate component employee/new-employee 



    You can see it creates/updates following files -
    • CREATE src/app/employee/new-employee/new-employee.component.css (0 bytes)
    • CREATE src/app/employee/new-employee/new-employee.component.html (31 bytes)
    • CREATE src/app/employee/new-employee/new-employee.component.spec.ts (664 bytes)
    • CREATE src/app/employee/new-employee/new-employee.component.ts (292 bytes)
    • UPDATE src/app/app.module.ts 

    Let's try to understand what each file is -
    • new-employee.component.ts : Components typescript file
    • new-employee.component.html : Components HTML file
    • new-employee.component.css:  Components CSS file
    • new-employee.component.spec.ts : File corresponding to the test for the component
    • src/app/app.module.ts : New Component is added to imports and declaration in the main module file.
    Now that we have generated our new component let's add some HTML for it. Notice it is similar to the root component in terms of file and structure. Root component is used to render the main page and all the remaining component can be rendered/navigated through the main component. Root component is always added in the bootstrap property of the main angular module. In our case it is AppComponent. Our code and directory structure should look like below -


    Now let's add some code to our new component. First, we will add some variables that we can dynamically set and bind in our HTML file. So go in the components typescript file (new-employee.component.ts) and add name and age as variables. In the ngOnInit method, initialize these to the values you want. So the typescript file looks like below -


    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-new-employee',
      templateUrl: './new-employee.component.html',
      styleUrls: ['./new-employee.component.css']
    })
    
    export class NewEmployeeComponent implements OnInit {
    
      name: string;
      age: number;
      constructor() { }
      ngOnInit() {
        this.name = "Aniket";
        this.age = 27;
      }
    }
    

    Now let's write the corresponding HTML file (new-employee.component.html). Remove any existing code that might be present there and add below code -

    <h1>Welcome to the Employee portal</h1>
    
    
    <h3>Name : {{name}}</h3>
    <h3>Age : {{age}}</h3>
    

    Notice how we are binding name and age variables from our typescript file. You can possibly change this values on events and the changes should immediately reflect in the rendered page.


    Now that we have our components HTML and typescript file ready let's do our navigation setup. Note you can also add your custom CSS in new-employee.component.css. To add navigation we will make changes in app-routing.module.ts file.

    If you remember our first tutorial we when we created our angular app we said setup routing to yes. This should create an app-routing.module.ts file for you. This should already have the boilerplate code for routing like importing router modules and exporting the module itself so that it can be imported into our main module. Make changes to this file so that it looks like below -

    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    import {NewEmployeeComponent} from './employee/new-employee/new-employee.component'
    
    const routes: Routes = [
      { path: 'newemployee', component: NewEmployeeComponent }
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    
    export class AppRoutingModule { }
    


    Here we have imported our new component. That's line -
    • import {NewEmployeeComponent} from './employee/new-employee/new-employee.component'
    Then we have added a route for this component in the empty array the boilerplate code had. This essentially says if anyone tried to access the "/newemployee" path then use the NewEmployeeComponent and render it to the router outlet. We will come to router outlets in a moment. 

    So that's the two changes we have done. Now go back to app.module.ts and verify that 
    1. NewEmployeeComponent is imported and added to the declaration section.  
    2. AppRoutingModule is imported and added to the imports section
    Once you have verified this, we have one last thing to do - add router outlet. Before I proceed let me summarize the angular bootstrap process that happens. We know our configuration is in the angular.json file which points to our main file main.ts that essentially bootstraps our main module app.component.ts. The main module will try to load the root component app.component.ts that has selector app-root by default. This selector is used in our main index.html page which us again configurable from angular.json. You can also notice that default index.html file has the tag   <app-root></app-root> in the body which is where our root component renders. You would also see that AppComponent which is our root component is listed in the bootstrap property in the main module. 


    As you must have already been wondering there is no routing support added so far. And that is correct. We need to tell angular where the component should render. And for this, we use a special tag called -
    • <router-outlet></router-outlet>
    So let's add this in our root component HTML file. So go to app.component.html and make changes so that it looks like below -


    <div class="hello-world">
      <h1>Hello World!</h1>
    
      <p>----------</p>
      <h1>Routed modules go below</h1>
      <p>----------</p>
      <router-outlet></router-outlet>
      <p>----------</p>
    </div>
    


    Notice that <router-outlet></router-outlet> tag I have added. This is where our new component would get rendered. Now go to the app in the command line and execute -
    • ng serve -o
    You should see below the screen when you navigate to -

    • http://localhost:4200/newemployee

    You can see how our new component got rendered inside our root component. Root component generally has the layout design and based on users navigation we can render the custom component. We will continue to see more angular concepts in upcoming posts. So stay tuned!




    Related Links

    Sunday, 18 November 2018

    Understanding angular application folder structure

    Background

    In the last post, we saw how to write a simple "Hello World!" application -
    In this post, I will try to explain the directory structure and importance of various files and folders in the angular project that we generated.


    NOTE: This is for angular 7. Folder structure and file names might be different in previous versions of angular.

     Understanding the angular application folder structure

     If you see the previous post the directory structure generated was as follows -


    We go try to see all the files and folders in the above picture and see what each does.

    e2e

    e2e stands for end to end. This consists of your end to end integration tests. these tests are run as if it is a real user testing but are actually simulated one. This includes opening a browser, navigating to the page, clicking on UI elements etc.


    This uses a package called protractor. You can find more details about protractor in https://www.protractortest.org/#/.

    node_modules

    If you are familiar with node environment this requires no special introduction. Angular app is essentially a node package. You can see there is a file called package.json in the root folder of your generated application. It defines dependencies of your node package. So that when you run "npm install" these dependencies are installed. These dependencies go under a folder called "node_modules" which is in the same folder as package.json. 


    src/app

    This folder is the source folder of your angular application. It contains all the source code that you write for your angular app to render. This will have files corresponding to your module, components, templates, css/saas files etc. The angular app will have at least one module and component.

    src/assets

     As the name suggests this folder should store all your static assets like images, icons etc.

    src/enviroments

    This folder contains the configuration for environments you define. By default, it would have 2 environments -
    1. environment.prod.ts : For production environment
    2. environment.ts  : For development environment

    favicon.ico

    This is the icon that gets showed when your browser loads your page.


    index.html

    This is the main HTML file that loads. You can see it has tag -
    • <app-root></app-root>
    This tag corresponds to the selector of bootstrap component(app.component.ts) that is defined in your root module(app.module.ts).


    main.ts

    This is our main type script file. Here we can bootstrap our module as -

    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
     
    

    polyfills.ts

    This type script file contains scripts that are needed by angular since the javascript feature may not be available in the browser. So basically it fills the gap to provide the features of JavaScript that are needed by Angular application and the features supported by your current browser.

    For example, IE may not support a File or a blob object. In this file, you can add your custom definitions.

    style.css

    This file contains your common styles that are global to the application. It could be a css or a saas file depending on what you choose during creation of your angular application.

    karma.conf.js

    This file is used to store the setting of Karma. Karma is used for unit tests while protractor that we saw above is used for end to end tests. For details see https://karma-runner.github.io/latest/index.html

    NOTE: Karma is a great tool for unit testing, and Protractor is intended for end to end or integration testing. This means that small tests for the logic of your individual controllers, directives, and services should be run using Karma. Big tests in which you have a running instance of your entire application should be run using Protractor. Protractor is intended to run tests from a user's point of view - if your test could be written down as instructions for a human interacting with your application, it should be an end to end test written with Protractor.

    test.ts

    This file is required for doing the testing setup.  This file is required by karma.conf.js and loads recursively all the .spec and framework files.


    angular.json

    This is the main file from which angular configuration is loaded. If you see this file it will have reference to all files - mian.ts, indes.html etc. All configuration needed for your angular application to build and run resides here.


    NOTE: In previous versions of angular this file was called angular-cli.json.


    package.json

    As mentioned in node_modules section, package.json is a descriptor file for any node project. It defines project name, it's dependencies etc.

    tsconfig.json

    This has configurations related to your typescript compiler. Your typescript compiler will look at these settings and converts type script to javascript that the browser understands.

    tslint.json

    This file has the liniting configuration. Rules that developers must follow to maintain the codebase in a standard way.

    .gitignore

    This is a file that git understands and whatever you add inside this file will be ignored by git for version control.




    Related Links

    Angular Hello World example

    Background

    In some of the earlier post, we saw Angular JS which is the older version of angular. 

    Current LTS version of angular is angular 6 (at the time of this writing). We will however be using angular 7 which is the active angular release.  In this post I will show you how to write a simple angular Hello World app. In the subsequent posts we will try to understand all files in the angular app and their purpose, angular routing, data binding etc.


    Angular CLI

    For generating angular app and it's components we are going to use Angular CLI (command line interface). You can see the wiki here. You need to have npm (node package manager) installed for this. If not please refer to my earlier posts on NodeJS(Links in the related section at the bottom).

    To install Angular CLI execute following command -
    • npm install -g @angular/cli 
     NOTE: You may have to run it with sudo of you are seeing permission issues. Once installed you can verify the installation by typing

    • ng --version



     Once angular CLI is installed you are all set to create your 1st angular app.



    Angular Hello World example

    Now let's create a new angular app, to begin with. To create a new angular application execute following command -

    • ng new angulardemo
     It if of format
    • "ng new projectname"

     You will now be asked for choices like would you like to add routing to the application. Would you be using CSS, SASS etc? For now, select Yes for routing and CSS as an option. We will see this later. For our current demo, these are not really essential.




     Once done you can go into the project directory and run.
    • ng serve -o
     This should build your app and open it in your browser.




     This is what the default application looks like. Now it's time to make some changes of our own. To do that open your application in your favorite IDE. I prefer using Visual Studio code. If you ae using this you can just open your project by going into the project directory and running -
    • code .
    The directory structure looks like below -



     As you can see there are bunch of files here but not to worry. We will see each in time. In this post, we will see how we can make changes and deploy our own code.


    The entry point is a file called angular.json. This file has all the configuration information used for building and developing your angular app. Look at the following part-


              "options": {
                "outputPath": "dist/angulardemo",
                "index": "src/index.html",
                "main": "src/main.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "src/tsconfig.app.json",
                "assets": [
                  "src/favicon.ico",
                  "src/assets"
                ],
                "styles": [
                  "src/styles.css"
                ],
                "scripts": []
              }
    

    You can see the important files we would have to check. You can see the index file is "src/index.html", the corresponding type file is "src/main.ts". Similarly, the CSS file is "src/styles.css". There are other files but not to worry about it as of now. We will just worry about these files for now.

    Now let's go to our index.html and here you can see the following tag -
    • <app-root></app-root>
    Now let's try to understand what would get rendered in this tag.  As I mentioned before the main file in "main.html" and corresponding typescript file is "main.ts". If you go to main.ts you will see -

    import { AppModule } from './app/app.module';
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
    


    This basically instructs to bootstrap a module called AppModule which is located at './app/app.module'. So go to this file. And you will see the following content in it -


    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    
    export class AppModule { }
    


    This is the main module of your Angular app. A module can have multiple components. An angular can have multiple modules as well. You can see in the above example it imports 2 modules BrowserModule, AppRoutingModule. You can see where it is imported from. The important part to see here is the bootstrap part because that is the component that actually gets rendered on loading an angular app. So lets go to ./app.component file.


    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    
    export class AppComponent {
      title = 'angulardemo';
    }
    


    Here you can see AppComponent is a component. Also, you can see it's selector is "app-root" which we saw in index.html. You can also see the HTML file and CSS file this component is using to render itself. So let's go its HTML file './app.component.html'. You can see this has some HTML code that got rendered when we ran "ng serve" command above.

    Time to make some changes. Remove this code completely and replace it with following code.


    <div class="hello-world">
      <h1>Hello World!</h1>
    </div>
    


    Notice we have added a class for the div called "hello-world". Let's add this class to our CSS file - './app.component.css'

     .hello-world {
        font-style: italic;
    }
    


    That's it. If you already have "ng serve -o" command running your changes should get reflected immediately in the browser. If you killed the command, run it again and you should see the changes reflecting in the browser.



    You can see in above picture that "Hello world!" comes in h1 tag and in italics()as our class defined it.





    Related Links

    Saturday, 27 October 2018

    Keep learning, Keep sharing!

    A wise man once said -
     If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.


    I crossed 40k reputation on Stack Overflow(SO).  And that accounts to 2544 rank in the world!




    It has been almost 5 and a half years since added my 1st answer to the site. And today 1,130 answers, 144 questions and a people reach of ~21.4 million later here I am going back to where it all started. I still remember the 1st answer that I wrote - it was downvoted just because an admin read it wrong and when he realized it, he was the 1st person to upvote the answer and that's how the journey began. I am taking this opportunity to stress a very important point - Knowledge increases by sharing.



    I am sure every developer has relied on some SO answers for finding directions to get their issues resolved. The reason I am sharing this today is to stress the point that if it has helped you, it would probably help a hundred others around the globe. So make sure to upvote that answer. If the answer did not work out for you but it helped you in the correct direction go ahead and add it as a new answer or a comment. Innovation is not always in doing different things, it can be doing things differently. Never hold back anything thinking the answer or question might be silly. You already know the outcome if you don't, so why not give it a try and see how it goes. If it's stupid but it works, it isn't stupid - as simple as that. Worst case scenario - someone correct you which not only helps you understand it better but also everyone else who is in the same boat. I personally consider this the best scenario - You don't learn anything if you think you are always right!



    Personally other than technical learning aspect of it, this has helped me a lot in terms of interviews, communicating with fellow developers and expanding personal reach. I get this question a lot during the technical interview - "Why do you have so many questions answered as compared to the questions asked with just 5 years of experience?". What I have learned during the course of last 5 years is that the same question has many different angles and like I said before if you are facing a problem there would be many others facing the same issue. It could be different OS, different library version, different runtime, a different flavor of language etc. I have always tried to add more content to the answers based on the issue I have faced and today based on the shown stats there are around 21.4 million developers who were in the same boat. That's a win-win scenario!


    I will conclude this post by saying - "Keep learning, Keep sharing!". Good luck :)

    Sharing few more stats - Just for fun :)







    PS: If you need my help in getting traction to your question in terms of upvote or bounties feel free to reach out to me at - opensourceforgeeks@gmail.com.

    Tuesday, 16 October 2018

    Lerna Tutorial - Managing Monorepos with Lerna

    Background

    Lerna is a tool that allows you to maintain multiple npm packages within one repository. There are multiple benefits of using such an approach - one repo, multiple packages. This paradigm is called monorepo (mono - single, repo - repository). You can read more about monorepo -
    To summarise pros are -
    • Single lint, build, test and release process.
    • Easy to coordinate changes across modules. 
    • A single place to report issues.
    • Easier to set up a development environment.
    • Tests across modules are run together which finds bugs that touch multiple modules easier.
    Now that you understand what a monorepo is, let's come back to Lerna. Lerna is a tool that helps you manage your monorepos. In this post, I am going to show you a complete tutorial of how you can use lerna to manage a custom multi package repo that we will create.





    Lerna Tutorial -  Managing Monorepos with Lerna

    First of all, you need to install lerna. Lerna is a CLI. To install it you need to execute following command -
    • npm install --global lerna
    This should install lerna in your local machine globally. You can run the following command to check the version of lerna installed -
    • lerna -v
     For me, it's 3.4.1 at the time of writing this post. Now let's create a directory for our lerna demo project.  Let's call it lerna-demo. You can create it with the following command -
    • mkdir lerna-demo 
    Now navigate inside this directory
    • cd lerna-demo
    Now execute following command -
    • lerna init
    This should create a basic structure of monorepo. Take a look at below picture to understand it's structure.


     It does following things -
    1. Creates packages folder. All packages go under this.
    2. Creates package.json at the root. This defines global dependencies. It has the dependency on lerna by default.
    3. Creates lerna.json at the root. This identifies lerna repo root.
     Now let's go to packages folder and start creating our packages. We will then see how we can link them and use. So navigate to packages directory.
    • cd packages

    Package - AdditionModule

    Let's create a package that takes care of addition. Let's call it AdditionModule. Create a directory for this inside packages folder and execute following commands -
    • mkdir AdditionModule 
    • cd AdditionModule 
    • npm init -y
    This should create a file called package.json inside AdditionModule directory. Now in the same folder create a file called index.js in the same folder and add following content to it -

    module.exports.add = function(x,y){
        return x + y;
    }
    


    Save the file. This basically exposes add method to any other package that would have a dependency on this. Your 1st package is done. Let's create one more package for subtraction.

    Package - SubtractionModule

     Run similar commands inside packages folder -

    • mkdir SubtractionModule
    • cd SubtractionModule
    • npm init -y
     Now in SubtractionModule folder create a file called index.js and add following code to it -

    module.exports.subtract = function(x,y){
        return x - y;
    }
    


    Save the file. This basically exposes subtract method to any other package that would have a dependency on this. Now let's create a package that would have a dependency on  AdditionModule and SubtractionModule and can use add and subtract functions.

    Package - Calc

    Our final package - let's call it Calc would have a dependency on  AdditionModule and SubtractionModule packages. So let's create the package 1st -

    • mkdir Calc
    • cd Calc
    • npm init -y
    Now create a file called index.js and add following content to it -

    var add = require('AdditionModule');
    var subtract = require('SubtractionModule');
    
    var sum = add.add(2,3);
    var diff = subtract.subtract(3,2);
    
    console.log("Sum: " + sum + " Diff: " + diff);
    

    Save the file. Now open package.json to add our dependencies. Edit package.json to add following content to it -

      "dependencies": {
          "AdditionModule": "1.0.0",
          "SubtractionModule": "1.0.0"
       },
    


    So your entire package.json looks like -

    {
      "name": "Calc",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
          "AdditionModule": "1.0.0",
          "SubtractionModule": "1.0.0"
       },
    }
    

    Now you are all set up. Your directory structure should look like below -



    Now it's time to use lerna to link packages. Go to lerna-demo directory and execute the following command -
    • lerna bootstrap
     This should do all linking for you. It would create node_modules directory in Calc package and add symlinks to AdditionModule and SubtractionModule. Your directory structure would now look like -


    Now you can simply run calc index.js as follows -

    • node packages/Calc/index.js
    And you should get expected output -




    The important thing was the linking part that lerna does for you so that you do not have to worry about it.


    For complete details on all available commands see - https://github.com/lerna/lerna

    Related Links




    Sunday, 14 October 2018

    What is the purpose of Node.js module.exports and how do you use it?

    Background

    If you have ever used nodejs and npm you must have encountered usage of module.exports syntax. Or perhaps just exports? If you do have encountered this that you might be aware that it exposes a certain functionality of the code so that other outside code can reference and execute it. Though this is a short version of what exports syntax does, in this post we will see a lot more of how it behaves and some examples to help us understand this better.










    What is the purpose of Node.js module.exports and how do you use it?

    The module.exports object is created by the Module system. module.exports is the object that's actually returned as the result of a require call. exports is just an alias to module.exports. So you could use either. There are some things that you would need to take care if you are just using exports but more of that later. For now, let's just take a simple example and see how it actually works.

    First, create a file called calc.js  with the following content -

    var add = function(x,y) {
    return x + y;
    }
    
    var subtract = function(x,y){
    return x - y;
    }
    
    module.exports = {
    add  : add,
    subtract: subtract
    };
    



    This code is simply defining two functions -  add and subtract and exporting them. Notice how these methods are declared as exports. We will revisit this back in a moment. Now let's try to use this code in a separate node code.

    Now create another file - Let's call it demo.js. Now in this file add following code -

    var calc = require('./calc.js');
    
    console.log("2 + 3 = " + calc.add(2,3));
    console.log("3 - 2 = " + calc.subtract(3,2));
    

    And finally, run the demo.js file as -

    • node demo.js
    It should give you the expected results -




    If you understood above logic you must have got a basic idea of how exports work. To revisit our earlier statement we said - "module.exports is the object that's actually returned as the result of a require call." In this case, it returns a map of add and subtract which point to corresponding functions that you can invoke.

    NOTE: Notice the "./" in the require statement. This is required to tell node that it is a local package.

    Another way to use the same module.exports would be as follows -

    module.exports.add = function(x,y) {
    return x + y;
    }
    
    module.exports.subtract = function(x,y){
    return x - y;
    }
    


    And if you now run demo.js again you would still see the same output. Both are just different ways to expose your code outside.

    NOTE: Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. So following will not work -


    var add = function(x,y) {
    return x + y;
    }
    
    var subtract = function(x,y){
    return x - y;
    }
    
    setTimeout(() => {
      module.exports = { add : add, subtract : subtract };
    }, 0);
    



    This will fail with below error -

    TypeError: calc.add is not a function
        at Object.<anonymous> (demo.js:3:31)
        at Module._compile (module.js:653:30)
        at Object.Module._extensions..js (module.js:664:10)
        at Module.load (module.js:566:32)
        at tryModuleLoad (module.js:506:12)
        at Function.Module._load (module.js:498:3)
        at Function.Module.runMain (module.js:694:10)
        at startup (bootstrap_node.js:204:16)
        at bootstrap_node.js:625:3
    



    So make sure your exports are done immediately and not in any callbacks.



    Now let's come back to the exports keyword that we said is just an alias to module.exports. Let us rewrite the code with just exports now.  Let's say your code is as follows -


    exports.add = function(x,y) {
    return x + y;
    }
    
    exports.subtract = function(x,y){
    return x - y;
    }
    


    Now run demo.js and you should still get your desired output. Like I said earlier exports is just an alias to exports.module. Now lets out 1st approach with just exports -

    var add = function(x,y) {
    return x + y;
    }
    
    var subtract = function(x,y){
    return x - y;
    }
    
    exports = {
    add : add,
    subtract: subtract
    }
    


    And if you run demo.js again you will get an error -

    TypeError: calc.add is not a function
        at Object.<anonymous> (demo.js:3:31)
        at Module._compile (module.js:653:30)
        at Object.Module._extensions..js (module.js:664:10)
        at Module.load (module.js:566:32)
        at tryModuleLoad (module.js:506:12)
        at Function.Module._load (module.js:498:3)
        at Function.Module.runMain (module.js:694:10)
        at startup (bootstrap_node.js:204:16)
        at bootstrap_node.js:625:3
    

    So why did this happen? This brings us to another crucial fact -

    If you overwrite exports then it will no longer refer to module.exports. The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated. So if you overwrite exports it is no longer an alias to module.exports and hence it no longer works.

    So make sure you do not overwrite exports variable. It is always safer to just use module.exports.

    To summarize this in a single picture module.exports work as follows -




    Related Links

    Thursday, 11 October 2018

    How to install Eclipse plugin manually from a local zip file

    Background

    Eclipse is an integrated development environment (IDE) used in computer programming and is the most widely used Java IDE. It contains a base workspace and an extensible plug-in system for customizing the environment. You can download Eclipse from their official site - 
    It also supports installing the plugin to customize your IDE environment. If you have already used Eclipse you might know how you can install a new plugin. All you need is the sites link where the plugin is hosted and you are all set. You can do this from
    • Help -> Install new Software



    In this post, I will show you how to install a plugin downloaded as a zip file from the local disk.

     How to install Eclipse plugin manually from a local zip file

    First, make sure your zip file is a valid Eclipse plugin. To verify that you can simply view contents of that zip. You should see two folders-
    1. features,
    2. plugins
    The new version of Eclipse might also have following files -
    1. content.jar, 
    2. artifacts.jar
    Eg.



     If above files exist then it means this is an archived update site. Once you have verified that your plugin zip file is correct it's time to get it installed.

    Now go back to
    • "Help" -> "Install New Software"
    Now click on "Add"


     Now click on "Archive"



     Now select the zip file you downloaded earlier. You can leave the name blank. Now click on Ok.

    You can now see the plugin details. Select it for installation. Make sure you unselect "Contact all update sites...." checkbox as it can sometimes create problems.

    Click "Next", accept terms and conditions and click "Finish".


    You should now see a warning that you are installing unsigned content.



    You can view the details if you want. Finally, click Ok and restart eclipse for changes to take effect.

     Once installed you can go to -
    • "Help" -> "Installation details" 
    to see the installed plugin details.



     You can also uninstall the plugin from here. Just click on the "Uninstall" button at the bottom.


    Related Links


    Saturday, 6 October 2018

    How to do iterative tasks with a delay in AWS Step Functions

    Background

    Very recently I did a video series on Building Web application using AWS serverless architecture -
    In one of the videos, I covered AWS step function service that can be used to create distributed applications using visual workflows.

    Step functions use Lambdas internally to execute business logic with the provided workflow. But there could be limitations that arise. Eg.
    1. The business logic that the Lambda is executing might take more than the maximum allowed time of 5 minutes.
    2. The API that you are calling from the Lambda might have the rate limiting.
    One straightforward way would be to break down the Lambda into multiple lambdas and execute the business logic. But it is not always possible. For eg. let's say you are importing some data from a site through an API and then saving it in your DB. You may not always have control over the number if user returned and processed. It is always a good idea to handle it on your end. Fortunately, step functions provide a way to handle such scenarios. In this post, I will try to explain the same.

     How to do iterative tasks with a delay in AWS Step Functions

     Let us assume we have the following flow -
    1. Get remote data from an API. Let's say we can process only 50 items in that data in a minute. Let's say the API that we call to process each item allows only 50 APIs per minute.
    2. Let's assume we get more than 50 items in the fetch API call. Now we have to batch 50 items at a time and process it.
    3. Wait for 60 seconds and then process the next batch of 50.
    4. Do this till all items fetched are processed.


    To do this we can use the following Step machine definition -


     {
        "Comment": "Step function to import external data",
        "StartAt": "FetchDataFromAPI",
        "States": {
            "FetchDataFromAPI": {
                "Type": "Task",
                "Resource": "arn:aws:lambda:us-east-1:499222264523:function:fetch-data",
                "Next": "ProcessData"
            },
    
            "ProcessData": {
                "Type": "Task",
                "Resource": "arn:aws:lambda:us-east-1:499222264523:function:process-data",
                "Next": "ProcessMoreChoiceState"
            },
    
            "ProcessMoreChoiceState": {
                "Type": "Choice",
                "Choices": [{
                    "Variable": "$.done",
                    "BooleanEquals": false,
                    "Next": "WaitAndProcessMore"
                }],
                "Default": "Done"
            },
    
            "WaitAndProcessMore": {
                "Type": "Wait",
                "Seconds": 60,
                "Next": "ProcessData"
            },
    
            "Done": {
                "Type": "Pass",
                "End": true
            }
        }
    }
    


    Visually it looks like below -




    If you have gone through the video link shared earlier most of this would have made sense to you by now. The only difference here is the "Wait" state that waits for 60 seconds before retrying.

    You will have to send the entire array and the number of items processed so far as output to "ProcessMoreChoiceState" and subsequently to "WaitAndprocessMore" state so that it can be sent back to "ProcessData" state again to process remaining entries. If all entries are processed we just set "done" variable to true which transitions to "Done" state finishing the state machine execution.

    Hope this helps. If you have any questions add it in the comments below. Thanks.

    Related Links

    Friday, 5 October 2018

    Building a web application using AWS serverless architecture

    Background

    The last couple of weeks I have tried to record Youtube videos to demonstrate how to build a web application using AWS serverless architecture.




    Serverless essentially means you do not have to worry about the physical hardware or the operating system or the runtimes. It's all taken care by the service offered under the serverless architecture. This has essentially given way to "Function as a service". 



    In this post, I will try to summarize what I have covered in those videos over the last 2 week so that anyone looking to put it all together can refer.
    If you do not wish to proceed and are just interested in the video links here's a list of them -

    1. AWS Serverless 101(Building a web application): https://youtu.be/I5bW0Oi0tY4
    2. AWS Serverless 102(Understanding the UI code): https://youtu.be/dQJCr0r_RuM
    3. AWS Serverless 103(AWS Lambda): https://youtu.be/Kn86Lq29IMA
    4. AWS Serverless 104(API Gateway): https://youtu.be/yKI_UCYblio
    5. AWS Serverless 105(CI/CD with code pipeline): https://youtu.be/GEWrpZuBEkQ
    6. AWS Serverless 106(Cloudwatch Events): https://youtu.be/9gUB2n0hV7Q
    7. AWS Serverless 107(Step functions): https://youtu.be/rL6EqaMbC5U

    Github repo: https://github.com/aniket91/AWS_Serverless

    I will go over each of the topics and explain what has been covered in each of the videos. If you think a specific topic interests you, you can pick that up. However, note that some videos might have references to setup done in previous videos. So it is recommended to go through them in the order provided. 


    AWS Serverless 101(Building a web application)




    This video is primarily to introduce you to the world of serverless. It covers a bit of cloud deployment history, information about serverless architecture - What and Why?. It also covers what are the prerequisites for this series and what exactly are we trying to build here. If you are completely new to AWS or AWS serverless concept this is a good place to start.

    This web application has a UI with a button on click on which an API call is made to get all the image files from an S3 bucket and are rendered on the UI. API call goes to API Gateway which forwards the request to Lambda. Lambda executes to get all the image files from S3 and returns it to API gateway which in turn returns the response to the UI code(javascript). Response is then parsed as json array and images are rendered on UI.

    AWS Serverless 102(Understanding the UI code)




    This video covers the UI component of the web application. This is in plain HTML and javascript. UI code is hosted on a static website in an S3 bucket.

    AWS Serverless 103(AWS Lambda)



    AWS Lambda forms the basic unit of AWS serverless architecture. This video talks about AWS Lambda - what is Lambda, How to configure it, How to use it and finally code to get the list of files from an S3 bucket.

    AWS Serverless 104(API Gateway) 




     API Gateway is an AWS service to create and expose APIs. This video talks about API Gateway service - how you can create APIs, resources, and methods, How we can integrate API gateway with Lambda. How to create stages and see corresponding endpoints. It also talks about CORS and logging in the API gateway service.

    AWS Serverless 105(CI/CD with code pipeline)




     This video shows how we can automate backend code deployment using code pipeline AWS service. This includes using Code pipeline, Code build, and Cloud formation services.

    AWS Serverless 106(Cloudwatch Events)



    This video shows how you can use Cloud watch events to trigger or schedule periodic jobs just like cron jobs in a Linux based system. We are using this service to do a periodic cleanup for non-image files in the S3 bucket.

     AWS Serverless 107(Step functions)





    This video covers how to use state machines of AWS step functions service to build distributed applications using visual workflows. We are using this service to do a asynchronous processing of various image files like jpg, png etc.

    Related Links


    t> UA-39527780-1 back to top