Category Archives: RSS Feed

Testing Angular with Jasmine and Karma (Part 1)

By Adam Morgan

Our goal

In this tutorial we will be building and testing an employee directory for a fictional company. This directory will have a view to show all of our users along with another view to serve as a profile page for individual users. Within this part of the tutorial we’ll focus on building the service and its tests that will be used for these users.

In following tutorials, we’ll populate the user profile page with an image of the user’s favorite Pokemon using the Pokeapi and learn how to test services that make HTTP requests.

What you should know

The primary focus for this tutorial is testing so my assumption is that you’re comfortable working with TypeScript and Angular applications. As a result of this I won’t be taking the time to explain what a service is and how it’s used. Instead, I’ll provide you with code as we work through our tests.

Why Test?

From personal experience, tests are the best way to prevent software defects. I’ve been on many teams in the past where a small piece of code is updated and the developer manually opens their browser or Postman to verify that it still works. This approach (manual QA) is begging for a disaster.

Tests are the best way to prevent software defects.

As features and codebases grow, manual QA becomes more expensive, time consuming, and error prone. If a feature or function is removed does every developer remember all of its potential side-effects? Are all developers manually testing in the same way? Probably not.

The reason we test our code is to verify that it behaves as we expect it to. As a result of this process you’ll find you have better feature documentation for yourself and other developers as well as a design aid for your APIs.

Why Karma?

Karma is a direct product of the AngularJS team from struggling to test their own framework features with existing tools. As a result of this, they made Karma and have transitioned it to Angular as the default test runner for applications created with the Angular CLI.

In addition to playing nicely with Angular, it also provides flexibility for you to tailor Karma to your workflow. This includes the option to test your code on various browsers and devices such as phones, tablets, and even a PS3 like the YouTube team.

Karma also provides you options to replace Jasmine with other testing frameworks such as Mocha and QUnit or integrate with various continuous integration services like Jenkins, TravisCI, or CircleCI.

Unless you add some additional configuration your typical interaction with Karma will be to run ng test in a terminal window.

Why Jasmine?

Jasmine is a behavior-driven development framework for testing JavaScript code that plays very well with Karma. Similar to Karma, it’s also the recommended testing framework within the Angular documentation as it’s setup for you with the Angular CLI. Jasmine is also dependency free and doesn’t require a DOM.

As far as features go, I love that Jasmine has almost everything I need for testing built into it. The most notable example would be spies. A spy allows us to “spy” on a function and track attributes about it such as whether or not it was called, how many times it was called, and with which arguments it was called. With a framework like Mocha, spies are not built-in and would require pairing it with a separate library like Sinon.js.

The good news is that the switching costs between testing frameworks is relatively low with differences in syntax as small as Jasmine’s toEqual() and Mocha’s to.equal().

A Simple Test Example

Imagine you had an alien servant named Adder who follows you everywhere you go. Other than being a cute alien companion Adder can really only do one thing, add two numbers together.

To verify Adder’s ability to add two numbers we could generate a set of test cases to see if Adder provides us the correct answer.

Within Jasmine, this would begin with what’s referred to as a “suite” which groups a related set of tests by calling the function describe.

// A Jasmine suite
describe('Adder', () => {

});

From here we could provide Adder with a set of test cases such as two positive numbers (2, 4), a positive number and a zero (3, 0), a positive number and a negative number (5, -2), and so on.

Within Jasmine, these are referred to as “specs” which we create by calling the function it, passing it a string to describe the functionality that’s being tested.

describe('Adder', () => {
  // A jasmine spec
  it('should be able to add two whole numbers', () => {
    expect(Adder.add(2, 2)).toEqual(4);
  });

  it('should be able to add a whole number and a negative number', () => {
    expect(Adder.add(2, -1)).toEqual(1);
  });

  it('should be able to add a whole number and a zero', () => {
    expect(Adder.add(2, 0)).toEqual(2);
  });
});

Within each spec we call expect and provide it what is referred to as an “actual”—the call site of our actual code. After the expectation, or expect, is the chained “matcher” function, such as toEqual, which the testing developer provides with the expected output of the code being tested.

There are many other matchers available to us other than toEqual. You can see a full list within Jasmine’s documentation.

Our tests aren’t concerned with how Adder arrives at the answer. We only care about the answer Adder provides us. For all we know, this may be Adder’s implementation of add.

function add(first, second) {
  if (true) { // why?
    if (true) { // why??
      if (1 === 1) { // why?!?1
        return first + second;
      }
    }
  }
}

In other words, we only care that Adder behaves as expected—we have no concern for Adder’s implementation.

This is what makes a practice like test-driven development (TDD) so powerful. You can first write a test for a function and its expected behavior and get it to pass. Then, once it’s passing, you can refactor your function to a different implementation and if the test is still passing, you know your function is still behaving as specified within your tests even with a different implementation. Adder’s add function would be a good example!

Angular setup

We’ll begin by creating our new application using the Angular CLI.

ng new angular-testing --routing

Since we’ll have multiple views in this application we use the --routing flag so the CLI automatically generates a routing module for us.

From here we can verify everything is working correctly by moving into the new angular-testing directory and running the application.

cd angular-testing
ng serve -o

You can also verify the application’s tests are currently in a passing state.

ng test

Adding a home page

Before creating a service to populate our home page with users, we’ll start by creating the home page.

ng g component home

Now that our component has been created, we can update our routing module’s (app-routing.module.ts) root path to HomeComponent.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  { path: '', component: HomeComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Run the application if it isn’t already and you should now see “home works!” below the default template in app.component.html which was created by the CLI.

Removing AppComponent tests

Since we no longer need the default contents of AppComponent, let’s update it by removing some unnecessary code.

First, remove everything in app.component.html so that only the router-outlet directive remains.

<router-outlet></router-outlet>

Within app.component.ts, you can also remove the title property.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent { }

Finally, you can update the tests in app.component.spec.ts by removing the two tests for some of the contents that were previously in app.component.html.

import { async, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});

Testing an Angular service

Now that our home page is set up we can work on creating a service to populate this page with our directory of employees.

ng g service services/users/users

Here we’ve created our users service within a new services/users directory to keep our services away from the default app directory which can get messy quick.

Now that our service is created, we can make a few small changes to the test file services/users/users.service.spec.ts.

I personally find injecting dependencies within it() to be a bit repetitive and harder to read as it’s done in the default scaffolding for our test file as shown below:

it('should be created', inject([TestService], (service: TestService) => {
  expect(service).toBeTruthy();
}));

With a few minor changes, we can move this into the beforeEach removing the duplication from each it.

import { TestBed } from '@angular/core/testing';
import { UsersService } from './users.service';

describe('UsersService', () => {
  let usersService: UsersService; // Add this

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [UsersService]
    });

    usersService = TestBed.get(UsersService); // Add this
  });

  it('should be created', () => { // Remove inject()
    expect(usersService).toBeTruthy();
  });
});

In the code above, TestBed.configureTestingModule({}) sets up the service we want to test with UsersService set in providers. We then inject the service into our test suite using TestBed.get() with the service we want to test as the argument. We set the return value to our local usersService variable which will allow us to interact with this service within our tests just as we would within a component.

Now that our test setup is restructured, we can add a test for an all method which will return a collection of users.

import { of } from 'rxjs'; // Add import

describe('UsersService', () => {
  ...

  it('should be created', () => {
    expect(usersService).toBeTruthy();
  });

  // Add tests for all() method
  describe('all', () => {
    it('should return a collection of users', () => {
      const userResponse = [
        {
          id: '1',
          name: 'Jane',
          role: 'Designer',
          pokemon: 'Blastoise'
        },
        {
          id: '2',
          name: 'Bob',
          role: 'Developer',
          pokemon: 'Charizard'
        }
      ];
      let response;
      spyOn(usersService, 'all').and.returnValue(of(userResponse));

      usersService.all().subscribe(res => {
        response = res;
      });

      expect(response).toEqual(userResponse);
    });
  });
});

Here we add a test for the expectation that all will return a collection of users. We declare a userResponse variable set to a mocked response of our service method. Then we use the spyOn() method to spy on usersService.all and chain .returnValue() to return our mocked userResponse variable wrapping it with of() to return this value as an observable.

With our spy set, we call our service method as we would within a component, subscribe to the observable, and set its return value to response.

Finally, we add our expectation that response will be set to the return value of the service call, userResponse.

Why mock?

At this point many people ask, “Why are we mocking the response?” Why did we provide our test a return value userResponse that we created ourselves, to manually set what’s being returned from our service? Shouldn’t the service call return the real response from the service, whether it’s a hard-coded set of users or a response from an HTTP request?

This is a perfectly reasonable question to ask and one that can be hard to wrap your head around when you first begin testing. I find this concept is easiest to illustrate with a real world example.

Imagine you own a restaurant and it’s the night before opening day. You gather everyone you’ve hired for a “test run” of the restaurant. You invite a few friends to come in and pretend they’re customers who will sit down and order a meal.

No dishes will actually be served in your test run. You’ve already worked with your cooks and are satisfied they can make the dishes correctly. In this test run you want to test the transition from the customer ordering their dish, to the waiter sending that to the kitchen, and then the waiters fulfilling the kitchen’s response to the customer. This response from the kitchen may be one of a few options.

  1. The meal is ready.
  2. The meal is delayed.
  3. The meal cannot be made. We ran out of ingredients for the dish.

If the meal is ready, the waiter delivers the meal to the customer. However, in the event that a meal is late or cannot be made, the waiter will have to go back to the customer, apologize, and potentially ask for a second dish.

In our test run, it wouldn’t make sense to actually create the meals when we want to test the front-end’s (waiter’s) ability to fulfill the requests received from the backend (kitchen). More importantly, if we wanted to test our waiters could actually apologize to customers in the cases where a meal is delayed or cannot be made we would literally be waiting until our cooks were too slow or we ran out of ingredients before our tests for those cases could be confirmed. For this reason, we would “mock” the backend (kitchen) and give the waiters whatever scenario it is that we want to test.

Similarly in code, we don’t actually hit the API when we’re testing various scenarios. We mock the response we may expect to receive and verify that our application can handle that response accordingly. Just like our kitchen example, if we were testing our application’s ability to handle an API call that failed we would literally have to wait for our API to fail to verify it could handle that case—a scenario that hopefully won’t be happening that often!

Adding users

To get this test to pass, we need to implement the service method in users.service.ts.

First, we’ll start by adding our imports and a collection of employees to the service.

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs'; // Add imports

@Injectable({
  providedIn: 'root'
})
export class UsersService {
  users: Array<object> = [  // Add employee object
    {
      id: '1',
      name: 'Jane',
      role: 'Designer',
      pokemon: 'Blastoise'
    },
    {
      id: '2',
      name: 'Bob',
      role: 'Developer',
      pokemon: 'Charizard'
    },
    {
      id: '3',
      name: 'Jim',
      role: 'Developer',
      pokemon: 'Venusaur'
    },
    {
      id: '4',
      name: 'Adam',
      role: 'Designer',
      pokemon: 'Yoshi'
    }
  ];

  constructor() { }
}

Then, just below our constructor, we can implement all.

all(): Observable<Array<object>> {
  return of(this.users);
}

Run ng test again and you should now have passing tests including the new tests for our service method.

Add users to the home page

Now that our service method is ready to use, we can work towards populating our home page with these users.

First, we’ll update index.html with Bulma to help us with some styling.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularTesting</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <!--Add these-->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
  <script defer src="https://use.fontawesome.com/releases/v5.1.0/js/all.js"></script>
</head>
<body>
  <app-root></app-root>
</body>
</html>

Then within home/home.component.ts we can add a call to our new service.

import { Component, OnInit } from '@angular/core';
import { UsersService } from '../services/users/users.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  users;

  constructor(private usersService: UsersService) { }

  ngOnInit() {
    this.usersService.all().subscribe(res => {
      this.users = res;
    });
  }

}

First we import our service and inject it into our component’s constructor. Then we add a call to the service method within ngOnInit and set the return value to our component’s users property.

To display these users to the view, update the template in home/home.component.html.

<section class="section is-small">
  <div class="container">
    <div class="columns">
      <div class="column" *ngFor="let user of users">
        <div class="box">
          <div class="content">
            <p class="has-text-centered is-size-5">{% raw %}{{user.name}}{% endraw %}</p>
            <ul>
              <li><strong>Role:</strong> {% raw %}{{user.role}}{% endraw %}</li>
              <li><strong>Pokemon:</strong> {% raw %}{{user.pokemon}}{% endraw %}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

Now when you run ng serve and view the home page, you should see the users displayed within Bulma boxes.

Finding a single user

Now that our users are being populated into our home page, we’ll add one more service method for finding a single user that will be used for the user profile pages.

First we’ll add the tests for our new service method.

describe('all', () => {
  ...
});

describe('findOne', () => {
  it('should return a single user', () => {
    const userResponse = {
      id: '2',
      name: 'Bob',
      role: 'Developer',
      pokemon: 'Charizard'
    };
    let response;
    spyOn(usersService, 'findOne').and.returnValue(of(userResponse));

    usersService.findOne('2').subscribe(res => {
      response = res;
    });

    expect(response).toEqual(userResponse);
  });
});

Here we add a test for the expectation that findOne will return a single user. We declare a userResponse variable set to a mocked response of our service method, a single object from the collection of users.

We then create a spy for usersService.findOne and return our mocked userResponse variable. With our spy set, we call our service method and set its return value to response.

Finally, we add our assertion that response will be set to the return value of the service call, userResponse.

To get this test to pass, we can add the following implementation to users.service.ts.

all(): Observable<Array<object>> {
  return of(this.users);
}

findOne(id: string): Observable<object> {
  const user = this.users.find((u: any) => {
    return u.id === id;
  });
  return of(user);
}

Now when you run ng test you should see all of the tests in a passing state.

Conclusion

At this point I hope testing, both its benefits and the reason for writing them, is starting to become a bit more clear. Personally, I pushed off testing for the longest time and my reasons were primarily because I didn’t understand the why behind them and resources for testing were limited.

What we’ve created in this tutorial isn’t the most visually impressive application but it’s a step in the right direction.

In the next tutorial, we’ll create the user profile page and a service to retrieve a Pokemon image using the Pokeapi. We’ll learn how to test service methods that make HTTP requests and how to test components.

Extra

If you want the tests to display in a more readable format within your terminal, there’s an npm package for this.

First, install the package.

npm install karma-spec-reporter --save-dev

Once that’s finished, open src/karma.conf.js, add the new package to plugins, and update the progress value within reporters to spec.

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular-devkit/build-angular/plugins/karma'),
      require('karma-spec-reporter') // Add this
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, '../coverage'),
      reports: ['html', 'lcovonly'],
      fixWebpackSourcePaths: true
    },
    reporters: ['spec', 'kjhtml'], // Update progress to spec
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};

Now when you run ng test you should have a more visually appealing output for your test suite.

Source:: scotch.io

My Top 8 Visual Studio Code Tips and Features

By Chris Ganga

Visual Studio Code has become one of the most used and loved Text Editors in recent years. Here are some statistics from the 2018 Stackoverflow Survey:- Most Popular Development Environments.

Source: https://insights.stackoverflow.com/survey/2018/

1. Visual Studio Code CLI

Visual Studio Code comes with an inbuilt Command Line Interface. Once you’ve installed Visual Studio Code, and have it open, press ⇧⌘P to open the command palette for Mac, or just ⌘P and the press > button.

Next, type in shell command, select Install Code Command in PATH, and press enter.

Now if you type in code, Visual Studio Code will open, and code , Visual Studio Code will open with the directory represented by Path.

To see the command line interface however, type in code -h.

code -h
Visual Studio Code 1.25.1

Usage: code [options] [paths...]

To read from stdin, append '-' (e.g. 'ps aux | grep code | code -')

Options:
  -d, --diff <file> <file>           Compare two files with each other.
  -a, --add <dir>                    Add folder(s) to the last active window.
  -g, --goto <file:line[:character]> Open a file at the path on the specified line and character position.
  -n, --new-window                   Force to open a new window.
  -r, --reuse-window                 Force to open a file or folder in an already opened window.
  -w, --wait                         Wait for the files to be closed before returning.
  --locale <locale>                  The locale to use (e.g. en-US or zh-TW).
  --user-data-dir <dir>              Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.
  -v, --version                      Print version.
  -h, --help                         Print usage.

I’ve truncated the output above, but there’s more to it. You can read through the commands and what they do, but you can see there are some very useful and handy tools in there. We’ll look at one --diff.

Ever wanted to see the difference between two files, Let’s look at an example. Here are two files with a slight difference in them.

app1.js

 var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue 1!'
  }
})

app2.js

 var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue 2!'
  }
})

This is a small file, and we can see the diff right away. But for demonstration purposes, we’ll type in the following in the command line.

code --diff app1.js app2.js

This opens Visual Studio Code with the following View.

We can see where the diff in the two files is. This is the same view that’s available when you are looking at Git Diff, with the integrated Git Support in Visual Studio Code.

2. Git Integration

Sometimes using Git can be fun or hard, but Visual Studio Code comes with integrated Git that allows for Adding, Committing, Pulling and Pushing Changes to a remote Git repository using a simple GUI.

Let’s go through a simple workflow that will involve the following steps.

  1. Create a project with git initialized.
  2. Make some changes
  3. Commit the changes

We have the two files we created app1.js and app2.js. Let’s initialize a git repository in this directory. And then open Visual Studio Code with this directory.

git init
code .

Where . represents the current directory your terminal is in.

You’ll immediately notice that Git is active in the left most pane. It has a badge with 2 on it.

The two files have a U in on their right, which means they are untracked. If you click on the git Icon with a badge of 2, you get this view. Hover over the first file app1.js, and these icons appear

The + sign is an equivalent of git add command. click it. and the view changes to this.

We can now see a Staged Changes section, with the file we’ve added, and the status has changed to A which represents Index Added.

Next, click on the Open File Icon on the file app1.js in the Staged Changes, and open the file. Edit the file to this. Replace message.

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Scotch!'
  }
})

Now, there’s a new entry in Changes section with the same file. When you click on the file app1.js in the Changes Section, you will see a diff displayed, like we saw in topic 1.

You can then click on the + sign to stage the changes. Committing the file to git is as simple as typing in the commit message at the top section with the Message (Press..., and pressing CMD + Enter or Ctrl + Enter. Below, I wrote Initial Commit
.

Pressing CMD + Enter, changes the view back to Changes only for the files we did not add.
.

Other helpful features that are git related include

  • A helpful Context Menu: – When you click on the menu icon ... within the Git Panel, this is what you see.

We see useful commands that are sometimes quite hard to grasp.

At the bottom of Visual Studio Code, in the status bar, you can also see the branch you are currently in. Clicking on that branch allows you to select any other branches that exist.

When you click on that, a list of branches appears in the search panel, with the first option being the ability to create a new branch

3. Debugging

Visual Studio Code has a rich API for enabling debugging tools, Here are some articles here in scotch referencing them.

  1. https://scotch.io/tutorials/debugging-javascript-in-google-chrome-and-visual-studio-code
  2. https://scotch.io/tutorials/debugging-node-code-in-vs-code
  3. https://scotch.io/@chenster/debugging-php-in-visual-studio-code205

Debugging is a large topic, and is usually language/stack specific. Depending on the language you are using, there are available plugins that enable support for debugging, and you’ll be able to use breakpoints to debug your code when developing.

4. Live Share

Visual Studio Code Live Share is a feature that enables you to share your VS Code instance, and allow someone remote to control and run other things such as debuggers.

Live Share is published as a plugin, and is currently in Preview.

All that is required is for you to install the plugin, and the status bar will enable you share any working session by getting a link, once you are signed in.

Here’s a Video, showing Visual Studio Code in action.

5. Split Views, Zen Mode

If you like working on multiple open editors in the same project, you will find this feature really interesting. You can press OPT, and click on a file, or right click on a file and choose Open to the Side, to open more the file in a split view like shown below.
.

There are a couple of built in Editor Layouts that you can view by going to the View > Editor Layout menu.

Below shows the 2×2 Grid Option

Zen Mode: Sometimes you want minimal distractions from everything, and only want to focus on your code. Below shows the zen mode, which can be accessed through the View > Toggle Zen Mode, or by opening the Command Palette, and typing in >Zen

Below shows the zen mode. Notice my code has been centered, and all other VS Code visuals removed.

6. Helpers (Intellisense, Context Menus..)

I decide to call this section helpers because it consists of little things that are quite helpful when writing code.

Here’s a simple JavaScript file we’ll use to demonstrate these features.

function name() {
  return "scotch"
}

function age() {
  return 8
}

function nameAndAge() {
  return {
    name: name(),
    age: age(),
  }
}
console.log(name())
console.log(age())
console.log(nameAndAge())
  • Peek Definition – this allows you to see the definition of a function/variable, without navigating to the it, even if it’s in a different file. It works with multiple languages, though sometimes you need to install the relevant plugins. To access it, right click in the line console.log(nameAndAge()), and click on peek definition in the context menu.
    .
    VS Code will find the function, and give you an overlayed editor to peek on what’s going on.

    You can also select Go To Definition, and you will be taken directly to where the function/variable is defined.
  • Find All References – This works pretty similar to Peek Definition. Right click on the function nameAndAge, and select Find All References.

    On the right of the overlayed editor, you will see a list of all the places the function has been referenced. This is useful in giving you an overview of how much a piece of code affects your whole codebase.
  • Rename Symbol – Also found in the context Menu, this allows you to rename a function or variable, and it will be changed everywhere it is referenced in the codebase.
  • Refactor – Currently, this works mainly for TypeScript and JavaScript, but it allows you to refactor code. e.g move a function into a file. In our example, if you right click on the nameAndAge function and click on refactor, one option will be Move To New File, and when you click on that, the function is removed, and put into a new file called nameAndAge.js
function nameAndAge() {
  return {
    name: name(),
    age: age(),
  };
}
  • Intellisense – Intellisense usually allows you to list members of a struct, class or object, and even get required parameters for functions, that makes writing code faster and less error prone. This is supported by default for JavaScript and TypeScript, but you may have to install language specific plugins to support the language you are using.

    You can also hover over anything:- variables, functions and see a pop up telling you more about them. Below is a hover over the log function in console
  • NPM Scripts – This sounds like it should be a feature in its own, but I’ll just put it here. NPM Scripts are usually commands that we put in the scripts section of the file package.json.
"scripts": {
    "start": "node index.js"
  }

VS Code has a couple of helpers for NPM. First of all, when you are creating the scripts, there’s beautiful intellisense and you can just select the script you want.

Next, there’s a NPM SCRIPTS panel on the left, usually at the bottom, which will list the package.json file, and within it the scripts. Right clicking on the file, gives you an option to run npm install
.
And Hovering over the particular script displays a Play button which will allow you run the script.

  • Outline – Outline was released recently, and I can’t believe how much I use it. It essentially gives you an overview of your code, and navigates to sections you click on.

Take for instance the piece of code we had earlier, if you open the file, and go to the Outline section on the left pane, you’ll see this

We see an outline of the main blocks of our code, and clicking on any of them, takes the editor focus to that section of the code.

These are just a few features and tips I didn’t know hot to categories. 😉

7. Integrated Terminal

Most of the time when running code, there’s usually a terminal open either to the side, or somewhere in your machine.

Visual Studio Code comes with an Integrated Terminal accessible through View > Integrated Terminal, and configurable through the settings: "terminal.external.osxExec": "iTerm.app",. The terminal usually opens by default in the workspace you are in, and can also have split views.

8. Plugins and Themes

Visual Studio Code has a rich plugin API, and this has enabled developers to create really awesome plugins. I’ll list a few common ones which I’ve used, but to get a comprehensive list, you can look at the Visual Studio Code Marketplace. Themes can be found here

  • Linters
    • ESLint – This enables us lint JavaScript ES code based on eslint rules we provide.
    • TSLint – This enables us link Typescript code based on tslint rules we provide
    • Prettier – Prettier is a common code formatter with growing popularity and enables linting of JavaScript, Typescript and CSS.
  • Language Support :- Visual Studio Code has syntax support for most common languages, but to get full language feature and tools, you will find yourself downloading language plugins. Since I write mostly JavaScript and Golang I have the vscode-go tools installed. You can see a list of language plugins here
  • Git – There are many plugins that add more support for Git, but the most common one is Git Lense. Here’s an example feature:

    Whenever you click on a line of code, it shows you who edited it, and a little more info about it. You can read more in the GitLense Documentation
  • Settings – The most common settings plugin is called Settings Sync, and allows you to sync your VS Code installations on different devices.
  • Docker – Developing with Docker can sometimes mean running complex docker commands, and monitoring things. Installing this Docker Extensions adds some helpful docker tools, such as generating docker files, docker files intellisense, and even monitoring. Here’s an example of my running containers in VS Code right now.

    Also comes with a useful context menu.

    If you are familiar with docker, you’ll find this plugin quite helpful.
  • NPM – I’ve already explained the inbuilt npm tools above. Here are a few plugins that make my npm work easier.
    • Version Lense – Easily manage versions of your npm packages.
    • Import Cost – Easily see the bytes every package import brings in your codebase.
  • Markdown All in One – this allows you to edit markdown as though you were writing a word document, and many other features. Useful if you write a lot of markdown.
  • Frameworks – I work mainly with VueJS and Golang, but there are a couple of plugins that support the various javascript frameworks.
    • Vetur – This gives support for VueJS
    • Angular Essentials – For Angular Developers.
    • React developers, please leave a comment, I’ll edit the article ;-).

Conclusion: Visual Studio Code can do that.

Visual Studio Code is a good Editor, that can adapt to many languages and technologies out there, and discovering these little helpers can sometimes take time.

Lucky for us, two awesome developers, @burkeholland and @sarah_edo created Visual Studio Code Can Do That site, that lists some awesome features and things you can do with Visual Studio Code.

Feel free to go through them.

Happy Coding!

Source:: scotch.io

Build a Reusable Component with Angular Elements

By Lee Brandt

Okta's sign up page.

Code reuse can be significant in any software project. By reusing code, developers can drastically cut development and maintenance time for software projects. This is the reason that every framework for developing software has a way to encapsulate functionality and reuse it. Whether it’s classes in C# and Java or modules in JavaScript, it’s a safe bet that you’ve considered extracting some piece of functionality to reuse it somewhere else. The only place that has never had a good story for reusing code is in HTML. Until now.

Projects like Stencil from the Ionic team, SkateJS, and now Angular Elements are making it easier than ever for developers to create components in the frameworks that they love and export them as Web Components so that they can use them in projects that may or may not be written in those frameworks. In this tutorial, I’ll show you how to create your first Angular Element and how to use it in a plain old HTML page!

What You’ll Need to Get Started with Angular Elements

You’ll need just a few things installed to get started with Angular Elements:

  • Angular CLI (version 6.0.8 at the time of this article)
  • NPM (I’m using version 6.2.0)
  • Node (I’m on version 10.8.0)

While it’s not necessary, I’m using Visual Studio Code. It’s super lightweight and works on all platforms.

Start Your Angular Project

Start up a new Angular project using the Angular CLI:

ng new login-element

You may notice that the generated project has quite a few vulnerabilities in the dependencies. You can fix all of them with npm audit fix --force from inside the login-element directory. I had no issues once this I did this, but double-check by running the project once you’ve fixed the vulnerabilities to check for yourself.

Once the Angular CLI has finished generating the new project and installing the dependencies, change into the login-element directory, and add @angular/elements to the package with the ng add command:

ng add @angular/elements --project=login-element

This command will add the @angular/elements packages and everything it needs to make web components including document-register-element, which is a lightweight version of the W3C Custom Elements specification. There is a problem with this package, however. The version installed at the time of writing is version 1.11.0, which I was unable to get working in Chrome 68. After some digging around in the GitHub repos for Angular elements, the suggestion that worked for me was to back the version of the Document Register Element package down to version 1.8.1 as it has better support across the browsers that support Custom Elements. The easiest way is to edit your package.json file and change the dependency document-register-element from ^1.7.2 to 1.8.1 and then re-run the npm install command. Remember, this is early days for Angular Elements, and the kinks are still being worked out.

Why Okta for Authentication?

Authentication is something almost every web application needs these days. It’s also one of those things that can be a real pain for developers. Not just the login screen, but an identity provider to handle creating and managing users. Since you’ll be creating a reusable login component, you’ll need to set up the identity service to handle user login and management. Okta is an excellent choice here as it will make creating, managing, and authorizing users a cinch.

You can sign up a free forever developer account, and you’re good to go!

Create an Okta Application

To get started, you’ll need to create an OpenID Connect application in Okta.

Once you’ve logged in and landed on the dashboard page, copy down the Org URL pictured below. You will need this later.

Okta developer dashboard highlighting the org URL.

Then create a new application by browsing to the Applications tab and clicking Add Application, and from the first page of the wizard choose Single-Page App.

Create application wizard with Single Page App selected.

On the settings page, enter the following values:

You can leave the other values unchanged, and click Done.

Application settings

Now that your application has been created copy down the Client ID value on the following page, you’ll need them soon.

The client ID

Lastly, you’ll need to bring in the @okta/okta-auth-js package to do the actual logging into Okta.

npm install @okta/okta-auth-js --save

Now, you’re ready to start creating your component!

Create Your Angular Element

For ease of use, you’ll use the app.component.ts file to create the login component. The selector won’t matter because when you set up the component to be exported, you’ll assign a selector then.

Your app.component.ts should look like:

import { Component, Input, ViewEncapsulation, OnInit } from '@angular/core';
import * as OktaAuth from '@okta/okta-auth-js';

@Component({
  selector: 'login-element',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  encapsulation: ViewEncapsulation.Native
})
export class AppComponent implements OnInit {
  @Input()
  companyName = 'ACME Corporation';

  @Input()
  oktaUrl: string;

  @Input()
  clientId: string;

  authClient: any;
  isAuthenticated: boolean;
  username: string;
  password: string;
  token: any;

  ngOnInit() {
    console.log(this.companyName, this.oktaUrl, this.clientId);
    this.authClient = new OktaAuth({
      url: this.oktaUrl,
      issuer: `${this.oktaUrl}/oauth2/default`,
      redirectUri: `http://localhost:${window.location.port}/implicit/callback`,
      clientId: this.clientId
    });

    this.token = this.authClient.tokenManager.get('idToken');
    if (this.token) {
      this.isAuthenticated = true;
      this.username = this.token.claims.email;
    } else {
      this.isAuthenticated = false;
    }
  }

  async login(username, password) {
    let signInResponse: any;

    try {
      signInResponse = await this.authClient.signIn({ username, password });
      if (signInResponse.status === 'SUCCESS') {
        this.token = await this.authClient.token.getWithoutPrompt({
          sessionToken: signInResponse.sessionToken,
          responseType: 'id_token',
          scopes: ['openid', 'email', 'profile']
        });
        if (this.token) {
          this.authClient.tokenManager.add('idToken', this.token);
          this.isAuthenticated = true;
          this.username = this.token.claims.email;
        }
      } else {
        throw `transaction status ${
          signInResponse.status
        } could not be handled.`;
      }
    } catch (error) {
      console.log(error);
    }
  }
}

There is a lot to discuss here. First, you’ve set the encapsulation for the component to ViewEncapsulation.Native. This will ensure your component uses the native Shadow DOM. You’ve also imported Okta’s JavaScript dependency.

Next, there are three @Input‘s here. The companyName is merely for display, but the oktaUrl and clientId will be needed for the login component to work. Making these inputs means that users of the component, can set these values to their own Okta Org Url and set their ClientId. Also, in the ngOnInit lifecycle method you check to see if the user has already logged in. This will get the user’s token from the tokenManager and set the component to display the welcome message instead of the login form if the user is already logged in when loading the page. This code will also handle a page refresh.

Lastly, the login() method. This uses the Okta authClient object to sign into Okta, and then get an id_token with the user’s email and profile once you’ve gotten a session token from Okta with a username and password. Both of these return promises that you’re awaiting to make things a little more readable.

Next, you’ll need the actual HTML elements for the component. Replace what’s in the app.component.html file with the following:

<section class="login-form">
  <h1>{{companyName}} Login</h1>
  <div *ngIf="!isAuthenticated">
    <input type="email" #username name="username" id="username" placeholder="username">
    <input type="password" #password name="password" id="password" placeholder="password">
    <button (click)="login(username.value, password.value)">Login</button>
  </div>
  <div class="greeting" *ngIf="isAuthenticated">
    Welcome {{username}}!
  </div>
</section>

The above code is very straightforward if you’ve done much Angular at all. It is just displaying the login form if the user is not logged in and a welcome message if they are. The login form’s button calls the login() method with the username and password entered.

Add a little styling to make it less boring:

.login-form {
  border: solid 1px #666;
  padding: 1rem;
  border-radius: 0.5rem;
  width: 25%;
  margin: auto;
}

input,
button {
  display: block;
  padding: 0.25rem;
  border-radius: 0.25rem;
  width: 95%;
  margin: 0.5rem;
}

.greeting {
  font-weight: bold;
  font-style: italic;
  font-size: 1.25rem;
}

Now you’ve got a component. All you need to do is to tell Angular that it is an Angular Element, and package it up so you can send it to all your friends!

Make the Component an Angular Element

To make sure Angular knows this is meant to be a reusable Angular Element component, you’ll need to make some changes to the app.module.ts file:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [],
  entryComponents: [AppComponent]
})
export class AppModule {
  constructor(private injector: Injector) {
    const el = createCustomElement(AppComponent, { injector });
    customElements.define('login-element', el);
  }
  ngDoBootstrap() {}
}

The first thing you might notice about the new module code is that it adds an entryComponents array to the @NgModule declaration. This tells Angular that rather than bootstrapping an Angular application from AppComponent, you’re going to compile it and package it up to use as a Web Component. Also, the AppModule now has a constructor to set up the createCustomElement() function that takes the AppComponent and the injector. The injector will be used to create new instances of the component that live independent of one another. Then you define the custom element and the selector login-element that will be defined for its use in other applications. The last ngDoBootstrap() method circumvents the natural bootstrapping of the element since it won’t be a regular Angular application.

Package Your Angular Element

Now you’re ready to package this thing up! There are several ways to do it, but here you’ll use a couple of simple node packages and create a Node script to package everything into one file. By default, the Angular CLI will create four files. To see them, try running:

ng build --prod

You’ll see a new dist folder with four JavaScript files in it. They’ll have hashes in the names, and be a little harder to work with than is practical for distributing to people to use in their applications. To avoid all this, install a couple of npm packages to help out:

npm install --save-dev concat fs-extra

Then create a file in the root of the project called build-elements.js that you’ll use in your npm scripts to pull all these into one file:

const fs = require('fs-extra');
const concat = require('concat');

(async function build() {
  const files = [
    './dist/air/runtime.js',
    './dist/air/polyfills.js',
    './dist/air/scripts.js',
    './dist/air/main.js'
  ];

  await fs.ensureDir('elements');
  await concat(files, 'elements/login-element.js');
})();

Now, to make sure it will run and find each of these files, add a new script to your package.json file. I added mine right after the generated build script:

"build:elements": "ng build --prod --output-hashing none && node build-elements.js",

This will run that ng build --prod with output hashing turned off so that the files won’t be named main.0476473b3749bc74928d.js, but rather just main.js, making it easy for the build-elements.js script to find and concatenate them.

Build it now by running:

npm run build:elements

You will see a new folder called elements in your root folder with one file: login-element.js which you can easily use anywhere.

Use Your Angular Element

In the new elements folder create an Index.html file and add the following contents, replacing the attribute values with your specific values:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <base href="/">
</head>

<body>

  <login-element company-name="{yourCompanyName}" okta-url="https://{yourOktaDomain}" client-id="{yourClientId}"></login-element>

  <script type="text/javascript" src="login-element.js"></script>

</body>

</html>

You can quickly run this by using a simple local HTTP server. `http-server is a simple package that serves any folder it is run in as a web folder. Install it with:

npm install -g http-server

Then run the HTTP server from inside the elements folder.

http-server

When you open http://localhost:8081, you will see the login component displayed. You can log in with your Okta user credentials and watch the component change to show your username in the welcome message.

Login Page Running

Now you have a single file that you can distribute and reuse to add an Okta login to any web application that needs it. Whether that app is written in Angular, React, Vue, or just plain old HTML and JavaScript.

Do Even More with Angular

Check out more tutorials on Angular:

If you have any questions, please don’t hesitate to leave a comment below, or ask us on our Okta Developer Forums. Don’t forget to follow us on Twitter @OktaDev, on Facebook and on YouTube!

Source:: scotch.io

Create Web Notifications Using Laravel and Pusher Channels

By Neo Ighodaro

When building web applications, it is not uncommon to find some sort of in-app notification system that will notify you instantly when someone carries out an action related to you or your account. On Facebook, you will be notified when someone likes your status, or when someone comments on your profile. We will replicate this feature by creating a web notifications system using Laravel and Pusher.

To follow this tutorial, you need to have PHP and Laravel installed on your machine.

What we would be building

After this tutorial we would demonstrate how we can have a small web application show notifications using Laravel and Pusher. It would be similar to how websites like Facebook show notifications. Here is a preview of what we would be building:

Setting up your Pusher application

Create a Pusher account, if you have not already, and then set up your application as seen in the screenshot below.

how-to-create-web-notifications-using-laravel-and-pusher-1

Setting up your Laravel application

You can create a new Laravel application by running the command below in your terminal:

laravel new laravel-web-notifications

After that, we will need to install the Pusher PHP SDK, you can do this using Composer by running the command below:

composer require pusher/pusher-php-server

When Composer is done, we will need to configure Laravel to use Pusher as its broadcast driver, to do this, open the .env file that is in the root directory of your Laravel installation. Update the values to correspond with the configuration below:

    PUSHER_APP_ID=322700
    BROADCAST_DRIVER=pusher

    // Get the credentials from your pusher dashboard
    PUSHER_APP_ID=XXXXX
    PUSHER_APP_KEY=XXXXXXX
    PUSHER_APP_SECRET=XXXXXXX

Important Note: If you’re using the EU or AP Cluster, make sure to update the options array in your config/broadcasting.php config since Laravel defaults to using the US Server. You can use all the options the Pusher PHP Library supports.

Open config/app.php and uncomment the AppProvidersBroadcastServiceProvider::class .

Creating our Laravel and Pusher application

Now that we are done with configuration, let us create our application. First we would create an Event class that would broadcast to Pusher from our Laravel application. Events can be fired from anywhere in the application.

php artisan make:event StatusLiked

This will create a new StatusLiked class in the app/Events directory. Open the contents of the file and update to the following below:

<?php

namespace AppEvents;

use IlluminateQueueSerializesModels;
use IlluminateFoundationEventsDispatchable;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateContractsBroadcastingShouldBroadcast;

class StatusLiked implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $username;

    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($username)
    {
        $this->username = $username;
        $this->message  = "{$username} liked your status";
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return ['status-liked'];
    }
}

Above, we have implemented the ShouldBroadcast interface and this tells Laravel that this event should be broadcasted using whatever driver we have set in the configuration file.

We also have a constructor that accepts two parameters, username and verb. We will get back to this later on. We assigned these variables to class properties named the same way. It is important to set the visibility of the properties to public; if you don’t, the property will be ignored.

Lastly, we set the channel name to broadcast on.

Creating the application views

We will keep it simple and create a single view where you can see a navigation bar with a notification icon. The icon will be updated when new notifications are available without the need to refresh the page. The notifications are ephemeral in this tutorial by design; you can extend the functionality and make it last longer after the page reloads if you so desire.

Open the welcome.blade.php file and replace it with the HTML below.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Demo Application</title>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="/css/bootstrap-notifications.min.css">
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <nav class="navbar navbar-inverse">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-9" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Demo App</a>
        </div>

        <div class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="dropdown dropdown-notifications">
              <a href="#notifications-panel" class="dropdown-toggle" data-toggle="dropdown">
                <i data-count="0" class="glyphicon glyphicon-bell notification-icon"></i>
              </a>

              <div class="dropdown-container">
                <div class="dropdown-toolbar">
                  <div class="dropdown-toolbar-actions">
                    <a href="#">Mark all as read</a>
                  </div>
                  <h3 class="dropdown-toolbar-title">Notifications (<span class="notif-count">0</span>)</h3>
                </div>
                <ul class="dropdown-menu">
                </ul>
                <div class="dropdown-footer text-center">
                  <a href="#">View All</a>
                </div>
              </div>
            </li>
            <li><a href="#">Timeline</a></li>
            <li><a href="#">Friends</a></li>
          </ul>
        </div>
      </div>
    </nav>

    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="//js.pusher.com/3.1/pusher.min.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

    <script type="text/javascript">
      var notificationsWrapper   = $('.dropdown-notifications');
      var notificationsToggle    = notificationsWrapper.find('a[data-toggle]');
      var notificationsCountElem = notificationsToggle.find('i[data-count]');
      var notificationsCount     = parseInt(notificationsCountElem.data('count'));
      var notifications          = notificationsWrapper.find('ul.dropdown-menu');

      if (notificationsCount <= 0) {
        notificationsWrapper.hide();
      }

      // Enable pusher logging - don't include this in production
      // Pusher.logToConsole = true;

      var pusher = new Pusher('API_KEY_HERE', {
        encrypted: true
      });

      // Subscribe to the channel we specified in our Laravel Event
      var channel = pusher.subscribe('status-liked');

      // Bind a function to a Event (the full Laravel class)
      channel.bind('AppEventsStatusLiked', function(data) {
        var existingNotifications = notifications.html();
        var avatar = Math.floor(Math.random() * (71 - 20 + 1)) + 20;
        var newNotificationHtml = `
          <li class="notification active">
              <div class="media">
                <div class="media-left">
                  <div class="media-object">
                    <img src="https://api.adorable.io/avatars/71/`+avatar+`.png" class="img-circle" alt="50x50" style="width: 50px; height: 50px;">
                  </div>
                </div>
                <div class="media-body">
                  <strong class="notification-title">`+data.message+`</strong>
                  <!--p class="notification-desc">Extra description can go here</p-->
                  <div class="notification-meta">
                    <small class="timestamp">about a minute ago</small>
                  </div>
                </div>
              </div>
          </li>
        `;
        notifications.html(newNotificationHtml + existingNotifications);

        notificationsCount += 1;
        notificationsCountElem.attr('data-count', notificationsCount);
        notificationsWrapper.find('.notif-count').text(notificationsCount);
        notificationsWrapper.show();
      });
    </script>
  </body>
</html>

This is mostly a lot of Bootstrap noise so we will isolate the important parts, mostly Javascript. We include the Pusher javascript library, and then we added the javascript block that does the magic. Let us look at some snippets of the javascript block:

// Enable pusher logging - don't include this in production
// Pusher.logToConsole = true;

// Initiate the Pusher JS library
var pusher = new Pusher('API_KEY_HERE', {
    encrypted: true
});

// Subscribe to the channel we specified in our Laravel Event
var channel = pusher.subscribe('status-liked');

// Bind a function to a Event (the full Laravel class)
channel.bind('AppEventsStatusLiked', function(data) {
    // this is called when the event notification is received...
});

PROTIP: By default, Laravel will broadcast the event using the event’s class name. However, you may customize the broadcast name by defining a broadcast as method on the event:
public function broadcastAs() {
return ‘event-name’;
}

The code above just initializes the Pusher JS library and subscribes to a channel. It then sets a callback to call when the event broadcasted is received on that channel.

Testing our set up

Finally to test our set up, we will create a route that manually calls the event. If everything works as expected, we will get a new notification anytime we hit the route. Let’s add the new route:

Route::get('test', function () {
    event(new AppEventsStatusLiked('Someone'));
    return "Event has been sent!";
});

Now we can start a PHP server using Laravel so we can test our code to see if it works.

$ php artisan serve

Conclusion

In this article we have been able to leverage the power of Pusher to create a modern web notifications system and it was very easy. This is just scratching the surface of what can be really done using Pusher. The example was just to show you the possibilities.

The code is available on GitHub, you can star, fork and play around with it.

Source:: scotch.io

Building CLI Applications with NodeJS

By Chris Ganga

As a developer, chances are you spend most of your time in your terminal, typing in commands to help you get around some tasks.

Some of these commands come built into your Operating System, while some of them you install through some third party helper such as npm, or brew, or even downloading a binary and adding it to your $PATH.

A good example of commonly used applications include npm, eslint, typescript, and project generators, such as Angular CLI, Vue CLI or Create React App.

Shebang

This is the wikipedia definition:

In computing, a shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script.

Whenever you look at any scripting file, you’ll see characters such as the ones below in the beginning of the file.

#!/usr/bin/env sh

#!/usr/bin/env python -c

They serve as a way for your operating system program loader will help parse the correct interpreter for your executable file. This only works in Unix Systems though.

NodeJS too has it’s own supported shebang characters. Make sure you have NodeJS installed, and create a file called logger with the following content.

#!/usr/bin/env node

console.log("I am a logger")

The first line tells the program loader to parse this file with NodeJS. The rest of the file is just normal JavaScript.

You can try and run the file by typing this in your terminal. You’ll get a permission denied for execution.

./logger
zsh: permission denied: ./logger

You need to give the file execution permissions. You can do that with.

chmod +x logger
./logger
I am a logger

You’ll see the file log correctly.

This could also easily be achieved if we did node logger. But we want to have our own command, and not need to use node ... to run it.

What we’ll build

Now that you have a teaser, we’re going to look at two example applications that we can build to learn more about CLI apps.

  1. Quote Of The Day (qod) cli tool, that retrieves quotes of the day from https://quotes.rest/qod.
  2. A Tiny To Do List that uses JSON to save data.

Quote of the Day

Let’s create a directory and call it qod. And inside, instantiate a NodeJs app.

mkdir qod
cd qod
touch qod
npm init -y

Next, we know we need to make requests to the quotes server, so we could use existing libraries to do just this. We’ll use axios

npm install --save axios

We’ll also add a chalk, a library to help us print color in the terminal.

npm install --save chalk

We then write the logic needed to retrieve these quotes. Edit the qod file.

#!/usr/bin/env node

const axios = require('axios')
const chalk = require('chalk');

const url = "https://quotes.rest/qod"

// make a get request to the url
axios({
  method: 'get',
  url: url,
  headers: { 'Accept': 'application/json' }, // this api needs this header set for the request
}).then(res => {
  const quote = res.data.contents.quotes[0].quote
  const author = res.data.contents.quotes[0].author
  const log = chalk.green(`${quote} - ${author}`) // we use chalk to set the color green on successful response
  console.log(log)
}).catch(err => {
  const log = chalk.red(err) // we set the color red here for errors.
  console.log(log)
})

The above is normal NodeJS code, and all we are doing is calling an API endpoint. Change the file permissions with

chmod +x qod

Then run the application.

./qod

The best way to not feel hopeless is to get up and do something. Don't wait for good things to happen to you. If you go out and make some good things happen, you will fill the world with hope, you will fill yourself with hope. - Barack Obama

It should appear green, as we stated with the color.

This is roughly the same as our first logger, but the point was to show that we can use existing libraries, and still run our apps the same way.

A Tiny To Do List

This will be a bit more complex, as it will involve data storage, and retrieval. Here’s what we’re trying to achieve.

  1. We need to have a command called todo
  2. The command will take in four arguments. new, get, complete, and help. So the available commands will be
./todo new // create a new todo
./todo get // get a list of all your todos
./todo complete // complete a todo item.
./todo help // print the help text

Seems straight forward.

Let’s create a directory called todo, and instantiate a nodejs app

mkdir todo
cd todo
touch todo
npm install -y

TIP – If you do a lot of creating directories and getting into the directories, you can save yourself some time by adding a function like this to your bash or zsh file.

# Create a new directory and enter it
function mkd() {
    mkdir -p "$@" && cd "$_";
}

Then, all you need to do is type in mkd directory_name, and you’ll be in there.

We’ll also install chalk again, so that we can log with colors.

npm install --save chalk

The first thing we’re going to do is make sure we have these commands available. To get the commands working, we’ll use NodeJs’ process/argv which returns a string array of command line arguments

The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched

Add this to the todo file.

#!/usr/bin/env node

console.log(process.argv)

Give the file executable permissions, and then run it with a new command.

chmod +x ./todo
./todo new

You’re going to get this output.

[ '/Users/ganga/.nvm/versions/node/v8.11.2/bin/node',
  '/Users/ganga/Dev/scotch/todo/todo',
  'new' ]

Notice that the first two strings in the array are the interpreter and the file full path. In this case, these are my absolute path names. Then, the rest of the array contains whatever we passed, in this case it’s new.

To be safe, let’s restrict these, so that we can only accept the correct number of arguments, which is one, and they can only be new, get and complete.

Modify the todo file like shown below.

#!/usr/bin/env node

const chalk = require('chalk')
const args = process.argv

// usage represents the help guide
const usage = function() {
  const usageText = `
  todo helps you manage you todo tasks.

  usage:
    todo <command>

    commands can be:

    new:      used to create a new todo
    get:      used to retrieve your todos
    complete: used to mark a todo as complete
    help:     used to print the usage guide
  `

  console.log(usageText)
}

// used to log errors to the console in red color
function errorLog(error) {
  const eLog = chalk.red(error)
  console.log(eLog)
}

// we make sure the length of the arguments is exactly three
if (args.length > 3) {
  errorLog(`only one argument can be accepted`)
  usage()
}

We’ve first assigned the command line arguments to a variable, and then we check at the bottom that the length is not greater than three.

We’ve also added a usage string, that will print what the command line app expects. Run the app with wrong parameters like below.

./todo new app
only one argument can be accepted

todo helps you manage you todo tasks.

usage:
  todo <command>

  commands can be:

  new:      used to create a new todo
  get:      used to retrieve your todos
  complete: used to mark a todo as complete
  help:     used to print the usage guide

If you run it with one parameter, it will not print anything, which means the code passes.

Next, we need to make sure only the four commands are expected, and everything else will be printed as invalid.

Add a list of the commands at the top of the code.

//....
const commands = ['new', 'get', 'complete', 'help']
//....

And then check with the passed in command after we’ve checked the length.

//...
if (commands.indexOf(args[2]) == -1) {
  errorLog('invalid command passed')
  usage()
}
//...

Now, if we run the app with an invalid command, we get this.

./todo ne
invalid command passed

  todo helps you manage you todo tasks.

  usage:
    todo <command>

    commands can be:

    new:      used to create a new todo
    get:      used to retrieve your todos
    complete: used to mark a todo as complete
    help:     used to print the usage guide

We’ll cover the rest of the logic in separate topics. For now, you can combine the argument checks into a single function as an exercises.

Todo App: Help Command

This is the most straight forward part of the app. All we need to do is call the usage function. Let’s add this to the todo file.

//...
switch(args[2]) {
  case 'help':
    usage()
    break
  case 'new':
    break
  case 'get':
    break
  case 'complete':
    break
  default:
    errorLog('invalid command passed')
    usage()
}
//...

We have a switch statement which will call functions based on what command has been called. If you look closely, you’ll notice the help case just calls the usage function.

While writing this I also noticed that the default case can serve as an error handler for invalid commands, so I deleted the check we did earlier, and the commands array. Thought I’d leave it there because refactoring is always fun.

Todo App: New Command

The new command will create a new todo item, and save it in a json file. We will use a file db, to help us with the storage files.

The library we will use is lowdb. We could easily write functions to read and write to a json file, if we wanted to.

Install lowdb

npm install --save lowdb

Let’s add [readline](https://nodejs.org/api/readline.html) and lowdb dependencies, to help us with storing data. The lowdb code is standard from their github page.

//...
const rl = require('readline');

const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')

const adapter = new FileSync('db.json')
const db = low(adapter)

// Set some defaults (required if your JSON file is empty)
db.defaults({ todos: []}).write()
//...

Next, we’ll add a function to prompt the user to input data.

//...
function prompt(question) {
  const r = rl.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
  });
  return new Promise((resolve, error) => {
    r.question(question, answer => {
      r.close()
      resolve(answer)
    });
  })
}
//...

Here we are using the readline library to create an interface that will help us prompt a user to and then read the output.

Next, we need to add a function that will be called when a user types in the new command

//...
function newTodo() {
  const q = chalk.blue('Type in your todon')
  prompt(q).then(todo => {
    console.log(todo)
  })
}
//...

We’re using chalk to get the blue color for the prompt. And then we will log the result.

Lastly, call the function in the new case.

// ...
switch(args[2]) {
  //...
  case 'new':
    newTodo()
    break
    // ...
}
// ...

When you run the app now with the new command, you will be prompted to add in a todo. Type and press enter.

./todo new
Type in your todo
This my todo  aaaaaaw yeah
This my todo  aaaaaaw yeah

You should see something similar to this.

Notice also, that a db.json file has been created in your file system, and it has a todos property.

Next, let’s add in the logic for adding a todo. Modify the newTodo function.

//...
function newTodo() {
  const q = chalk.blue('Type in your todon')
  prompt(q).then(todo => {
    // add todo
    db.get('todos')
      .push({
      title: todo,
      complete: false
      })
      .write()
  })
}
//...

Run the code again.

./todo new
Type in your todo
Take a Scotch course

If you look at your db.json, you’ll see the todo added. Add two more, so that we can retrieve them in the next get command. Here’s mine.

{
  "todos": [
    {
      "title": "Take a Scotch course",
      "complete": false
    },
    {
      "title": "Travel the world",
      "complete": false
    },
    {
      "title": "Rewatch Avengers",
      "complete": false
    }
  ]
}

Todo App: Get Command

With knowledge from the new command, the get command should be simple to write.

Create a function that will retrieve the todos.

//...
function getTodos() {
  const todos = db.get('todos').value()
  let index = 1;
  todos.forEach(todo => {
    const todoText = `${index++}. ${todo.title}`
    console.log(todoText)
  })
}
//...

// switch statements
switch(args[2]) {
    //...
    case 'get':
        getTodos()
        break
    //...
}
//....

Running the app now, should give us this

./todo get
1. Take a Scotch course
2. Travel the world
3. Rewatch Avengers

You can make the color fancy/green by using chalk.green

TodoApp: Complete Command

The complete command is a little bit complicated.

We can do it in two ways.

  1. Whenever a user types in ./todo complete, we could list all the todos, and the ask them to type in the number/key for the todo to mark as complete.
  2. We can add in another parameter, so that a user can type in ./todo get, and then choose the task to mark as complete with a parameter, such as ./todo complete 1.

Since we covered how option 1 is done in the new command, we’ll look at option 2.

A good problem introduced here is the ./todo complete 1, will surely surpass our validity check for the number of commands given. We therefore first need to handle this. Change the function that checks the length of the arguments with to this.

//...
// we make sure the length of the arguments is exactly three
if (args.length > 3 && args[2] != 'complete') {
  errorLog('only one argument can be accepted')
  usage()
  return
}
///...

Above approach is using the truth tables, where TRUE && FALSE will equal FALSE, and the code will be skipped when complete is passed.

We’ll then grab the value of the new argument and make the value of todo as completed like so

//...
function completeTodo() {
  // check that length
  if (args.length != 4) {
    errorLog("invalid number of arguments passed for complete command")
    return
  }

  let n = Number(args[3])
  // check if the value is a number
  if (isNaN(n)) {
    errorLog("please provide a valid number for complete command")
    return
  }

  // check if correct length of values has been passed
  let todosLength = db.get('todos').value().length
  if (n > todosLength) {
    errorLog("invalid number passed for complete command.")
    return
  }

  // update the todo item marked as complete
  db.set(`todos[${n-1}].complete`, true).write()
}
//...

I’ve made comments on each part of the code above. Please read through.

Make sure to update the switch statements.

//...
case 'complete':
    completeTodo()
    break
//...

When you run this with ./todo complete 2, you’ll notice your db.json has changed to this, marking the second task as complete.

{
  "todos": [
    {
      "title": "Take a Scotch course",
      "complete": false
    },
    {
      "title": "Travel the world",
      "complete": true
    },
    {
      "title": "Rewatch Avengers",
      "complete": false
    }
  ]
}

The last thing we need to do, is change ./todo get to only show tasks that are done. We’ll use emojis for this.

//...
function getTodos() {
  const todos = db.get('todos').value()
  let index = 1;
  todos.forEach(todo => {
    let todoText = `${index++}. ${todo.title}`
    if (todo.complete) {
      todoText += ' ✔ ️' // add a check mark
    }
    console.log(chalk.strikethrough(todoText))
  })
  return
}
//...

When you now type in the ./todo get you’ll see this.

./todo get
1. Take a Scotch course
2. Travel the world ✔ ️
3. Rewatch Avengers

I know, it could be improved, but you get the idea.

That’s it for now.

Libraries

This is JavaScript, and of course some brilliant person out there has thought of all these and written helper libraries. The focus for this article was to look at how CLI applications are built with vanilla nodejs, but when working in the real world, it would be more productive to use libraries.

Here’s a list of helpful libraries to help you write awesome CLI applications, which you can publish to npm.

  1. vopral – fully featured interactive CLI framework
  2. meow – CLI helper library
  3. commanderjs – CLI library
  4. minimist – for arguments parsing
  5. yargs – arguments parsing

And not to mention libraries like chalk that helped us with colors.

Recap

I hope you got a thing or two about building CLI applications with NodeJS.

A common practice I did not mention is that, once your app is working fine, most libraries put the file into a bin folder, and this way, npm knows how to work with executables. This is not a requirement, but regardless of where you place the executable, you should update package.json bin property.

As an excercise, try to add a Delete command to the CLI.

Happy Coding.

Source:: scotch.io

​DDoS Protection Mastery Starts Here

By SergiuHKR

We’re very excited to announce the launch of the online DDoS Protection Bootcamp. Built for IT security and network ops professionals, this one-of-a-kind online training portal offers an unprecedented selection of free courses and challenging quizzes that test and improve your DDoS protection skills.

Jointly prepared by Imperva Incapsula and DDoS testing firm NimbusDDoS, the DDoS Protection Bootcamp leverages the domain expertise of both companies to offer in-depth technical training in DDoS protection. Until now, you literally had to work for a security company to have access to this level of knowledge.

Unlike other training sites, the DDoS Protection Bootcamp is uniquely designed to combine rich educational content with a fun online quiz-based format that lets you measure your knowledge as you progress through the topics. Each quiz question comes with a complete explanation of the right answer so you can learn from your mistakes.

What You’ll Learn at the DDoS Protection Bootcamp

Recent studies indicate that almost 75 percent of organizations have suffered at least one DDoS attack over the past 12 months. This is not a problem that’s going away. The DDoS Protection Bootcamp gives trainees the technical knowledge and skills to identify and block different types of DDoS attacks.

This comprehensive course covers the following topics:

  • Introduction to DDoS
  • Volumetric Attacks
  • Protocol Attacks
  • Application Level (Layer 7) Attacks
  • Reflection Attacks
  • Understanding Risks
  • Mitigation Techniques
  • DDoS Trends

The training is divided into Basic and Advanced levels so you can choose the courses that best match your needs and proceed at your own pace. As noted, the educational content for each topic is followed by a quiz whose level of difficulty depends on the course level. The course concludes with a final exam covering all eight topics.

Get started today

If you’re ready to step up your game, the DDoS Protection Bootcamp is a great way to get into top professional shape.

Check it out today — It’s absolutely free and no registration is required. You’re also more than welcome to invite a friend or colleague to join you.

Like any new training course, your feedback is invaluable. Let us know what you liked, what you didn’t like and where we can improve. Enjoy!

Source:: scotch.io

Debugging Angular CLI Applications in Visual Studio Code

By James Quick

Learn VS Code

Debugging Angular CLI Applications in Visual Studio Code

In this post, we are going to create an Angular CLI application, then add configuration to debug it in Visual Studio Code.

Watch on YouTube

TLDR – For an Angular CLI application, create a debug configuration in VS Code, install the Debugger for Chrome extension, then run in debug mode.

Learn VS Code

If you’re interested in learning more about VS Code, you definitely want to check out the upcoming Learn VS Code course.

Creating a Starter Project

To be able to test an Angular CLI application, you need an Angular CLI application 🙂 I’ll provide the basic steps, but for more reference on how to get started look at the Angular CLI page.

Angular CLI

First, you’ll need to install the Angular CLI.

npm install -g @angular/cli

After that finishes, you’ll need to actually generate your new application. This will take a bit as it needs to install LOTS of NPM packages.

ng new my-app

Open the project in VS Code and you should see the following.

Angular CLI Project in VS Code

Now, that you’ve got your new fancy Angular app, go ahead and run it to make sure everything looks right.

ng serve

Should look like this.

Angular CLI App Running

Creating Debug Configuration

Assuming you’ve made it this far, we are ready to start debugging! Before we do, however, it’s worth understanding how configuring debugging in VS Code works. Basically debug configurations are saved in a launch.json file which is stored inside of a .vscode folder. This .vscode folder is used to store different configurations for Code including our required debugging stuff.

Before you create your debug configuration, you need to install the Debugger for Chrome extension. Find and install this extension from the extension tab in VS Code. After installing, reload VS Code.

Debugger for Chrome

Now, to create a debug configuration, you can open the debug panel (the bug looking button on the left panel). At the top of the debug panel, you should see a dropdown that says “No Configurations”.

Create Debug Configurations

To the right of that dropdown, there is a gear icon. Click this button to have VS Code automatically generate that .vscode folder and launch.json file mentioned above.

Then choose Chrome.

You should get the following configuration created for you.

Angular CLI Debug Configuration

The only thing we need to do is update the port from 8080 to 4200.

Updated Angular CLI Debug Configuration

Let’s Debug

Now we’re ready! Go ahead and click the play button at the top of the Debug panel which will launch an instance of Chrome in debug mode. Keep in mind your app should already be running from using ng serve earlier. In VS Code, you should see the Debug toolbar pop up.

With this up and running, you can set a breakpoint in your App.component.ts. Open up your App.component.ts and add a breakpoint inside of the component by clicking in the gutter (to the left of the line numbers). Should look like this.

Now, refresh debugging by clicking the refresh button on the debugging toolbar. This should open your application again and trigger this breakpoin. You should be directed back to VS Code directly to the place where you set your breakpoint.

From here, you can set more breakpoints, inspect variables, etc. If you are interested in learning more about debugging JavaScript in general in either Chrome or VS Code you can check out Debugging JavaScript in Chrome and Visual Studio Code.

Again, if you’re interested in learning more about VS Code, you’ll definitely want to check out the upcoming Learn VS Code course.

If you have any follow up questions or comments, leave one below of find me on twitter @jamesqquick.

For video content, check out my YouTube Channel

Source:: scotch.io

Getting Started with Component Transitions in Vue

By Chris Nwamba

Vue Transition Diagram

When we build applications, we aim to make them easy on the eye. We want our users to have a smooth experience using it, and to feel our application flowing from one point to another, rather than just jump between screens.

If we switch components without transitions, we see a sharp change every time a new component is called up. This is not ideal and can result in our users having a poor experience with our application.

In this tutorial, we will look at how to improve the flow of our application using component transitions in Vue.

Prerequisites

  1. Vue CLI 3 for installing Vue
  2. Knowledge of JavaScript
  3. Knowledge of Vue.js

Setup Our Application

To begin, we will create a Vue application. Run the following command:

$ vue create component-transitions
$ cd component-transitions

Once we are done creating the application, we need to define a component we will use for the transitions.

Update The App Component
When we create a new Vue application, the CLI creates an App.vue file inside the ./src directory. Open the file and update the style section as follows:

[...]
<style>
    [...] 
    h3 {
        margin: 40px 0 0;
    }
    ul {
        list-style-type: none;
        padding: 0;
    }
    li {
        display: inline-block;
        margin: 0 10px;
    }
    a {
        color: #42b983;
    }
</style>

We created global styles we wish to share across all our components. This way, we will not have to add styles per component again.

Update The HelloWorld Component
Our Vue application also comes with a HelloWorld.vue file in located in ./src/components directory. Open the file and edit as follows:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'HelloWorld',
        props: {
            msg: String
        }
    }
</script>

Create The About Component
We are going to create a new component About.vue inside the ./src/components directory. Open the file and add the following:

<template>
    <div>
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'About',
        props: {
            msg: String
        }
    }
</script>

Create Another Component
We are going to create another component Extra.vue inside the ./src/components directory. Open the file and add the following:

<template>
    <div>
        <h1>{{ intro }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'Extra',
        props: {
            msg: String
        },
        data(){
            return {
                intro : "Extra"
            }
        },
        watch: {
            msg : {
                immediate: true, 
                handler(val, oldval) {
                    //
                }
            }
        }
    }
</script>

For our extra component, we have added a watch method to track the updates to the msg prop. When the message prop updates, we want to update the intro property.

We defined it this way to allow us to use transitions on the component.

Rendering Our Components

Vue provides a variety of ways to apply transition effects when items in a component are updated or when components themselves are changed. It ranges from applying CSS classes for transitions and animations to using 3rd party JavaScript libraries for transition effects.

The first set of transitions we will define will be on change of components. We will use conditional rendering to display the components we created and apply transition as they render.

Import The Components
We need to import the components we created into our App.vue component. Open the file and edit as follows:

[...]
<script>
    import HelloWorld from './components/HelloWorld.vue'
    import About from './components/About.vue'
    import Extra from './components/Extra.vue'

    export default {
        name: 'app',
        components: {
            HelloWorld, About, Extra
        }
    }
</script>

Use The Components
Now that we have imported the components, let us use it in our App component. Edit the App.vue file as follows:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <HelloWorld msg="Welcome to your Vue.js application"/>
        <Extra :msg="extra"/>
        <About msg="This is the About page"/>
        <button @click="changeExtra">Update Extra</button>
    </div>
</template>

We defined a function changeExtra to listen for button clicks and also bound the msg prop for the Extra component to extra attribute. Now, let’s create the extra attribute and changeExtra method. We will just leave the Vue.js logo there so the page doesn’t feel empty 😁

Edit the file as follows:

[...]
export default {
    name: 'app',
    components: {
        HelloWorld, About, Extra
    },
    data(){
        return {
            extra : "Extra"
        }
    },
    methods : {
        changeExtra(){
            this.extra = "This is extra"
        }
    },
}
[...]

Define Links For Switching Components
We are going to show one component at a time. To do this, we will have a simple set of links that would allow us to state which component to use at a certain time.

Open the App.vue file and add the following:

<template>
    <div id="app">
        [...]
        <div>
            <ul>
                <li @click="showHome">Home</li>
                <li @click="showAbout">About</li>
                <li @click="showExtra">Extra</li>
            </ul>
        </div>
    </div>
</template>

Then add the methods we used above:

[...]
methods : {
    [...]
    showHome(){
        this.displayHome = true
        this.displayAbout = false
        this.displayExtra = false
    },
    showAbout(){
        this.displayHome = false
        this.displayAbout = true
        this.displayExtra = false
    },
    showExtra(){
        this.displayHome = false
        this.displayAbout = false
        this.displayExtra = true
    }
},
[...]

Finally, we define the properties — displayHome, displayAbout, displayExtra.

[...]
data(){
    return {
        extra : "Extra",
        displayHome : true,
        displayAbout : false,
        displayExtra : false
    }
},
[...]

We set displayHome to true so that anytime we load our application, it shows up first. The rest is false so they do not show up.

Conditional Rendering Of Our Components
Now that we have defined links for showing our components, let’s render them based on certain conditions.
Still in the App.vue file, edit it as follows:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <HelloWorld msg="Welcome to your Vue.js application" v-if="displayHome"/>
        <About msg="This is the About page" v-if="displayAbout"/>
        <div v-if="displayExtra">
            <Extra :msg="extra"/>
            <button @click="changeExtra">Update Extra</button>
        </div>
        [...]
    </div>
</template>

So, we have completely rendered all of our components, now we can add transitions to it. Hurray!!!

Defining Transitions On Data Change

We will modify Extra component. We want to add a simple transition effect when we update the data inside of it. Open the Extra.vue file in the ./src/components/ directory and edit as follows:

<template>
    <div>
        <transition name="fade">
            <h1 v-if="!msg">{{ intro }}</h1>
        </transition>
        <transition name="fade">
            <h1 v-if="msg">{{ msg }}</h1>
        </transition>
    </div>
</template>
[...]
<style scoped>
   .fade-enter-active{
        transition: opacity 1.5s;
    }
    .fade-leave-active {
        opacity: 0;
    }
    .fade-enter, .fade-leave-to {
        opacity: 0;
    }
</style>

This is a simple component. When we click the Update Extra button, we will notice a slide fading transition occur. The transition is very noticeable, so our users must see it.

We are able to achieve the transition by wrapping our element in a Vue transition element and then defining the effect we want the transition element to use. In our case, we used opacity to make the component appear and disappear.

For data change transitions, you might want to use state transition as it provides a more robust experience. Read more about State Transitions.

Vue provides hooks at different stages of the transition cycle that we can hook into and define how we want the transition to be. I’ve added an image below from Vue.js website to illustrate this:

v represents the name of our transition. In the case of the Extra component, we replace v with fade to have fade-enter in place of v-enter and so on.

Defining Transitions On Component Change

Define Transition On The HelloWorld Component
Now, to the App component where we will explore different other ways to implement transitions. Let’s define the transition on the HelloWorld component. Open the App.vue file and edit as follows:

<transition name="welcome">
    <HelloWorld msg="Welcome to your Vue.js application" v-if="displayHome"/>
</transition>

Our transition will be named “welcome”. Now, add the transition classes to get your desired effect:

<style scoped>
    /* Welcome Styles */
    .welcome-enter {
        transform: translateX(10px);
        opacity: 0;
    }
    .welcome-enter-active {
        transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .welcome-leave-active, .welcome-leave-to {
        opacity: 0;
    }
</style>

Now, every time we click the Home link, there will be a little shaking 😀 as our component it shows.

PS: We created a new style element and added ‘scoped` to it.

Define Transition On The About Component
We will take a similar step with what we did for the HelloWorld component. Open the file and add the following:

[...]
<transition name="about">
    <About msg="This is the About page" v-if="displayAbout"/>
</transition>
[...]

Then add the transition effect:

<style scoped>
    [...]
    /* About Styles */
    .about-enter {
        width: 30%;
        opacity: 0;
    }
    .about-enter-active {
        transition: all 2s ease-in-out;
    }
    .about-leave-active, .about-leave-to {
        opacity: 0;
    }
    .about-enter-to {
        width:100%;
        opacity: 1;
        margin-left: auto;
    }
</style>

Define The Transition On Extra Component
Finally, let’s also add a transition for enter and exit of the extra component:

[...]
<transition name="extra">
    <div v-if="displayExtra">
        <Extra :msg="extra"/>
        <button @click="changeExtra">Update Extra</button>
    </div>
</transition>
[...]

Then add the styles for the transition:

<style scoped>
    [...]
    /* Extra Styes */
    .extra-enter {
        transform: translateX(-200px);
        opacity: 0;
    }
    .extra-enter-to {
        transform: translateX(0px);
    }
    .extra-enter-active {
        transition: all 1s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .extra-leave-active, .extra-leave-to {
        opacity: 0;
    }
</style>

And that’s it for component transitions.

Run The Application

Now that we are done defining transitions for our various components, let’s run the application and see what it looks like.

From your terminal, run the following command:

$ npm run serve

Then visit the application on the url that appears.

See A Demo

Conclusion

We have looked at vue component transitions in this tutorial. We saw how easy it is to add transitions to our application. I have to admit we kind of overdid the transition thing and used effects we may not want to use in a real application. The entire goal was to show that anything is possible.

Try to use different CSS transitions for your components and see what you can come up with.

Source:: scotch.io

Building a Portfolio Carousel with Synchronized Sliders

By Luis Manuel

Portfolio Carousel

Undoubtedly, one of the fundamental sections that every personal or business website must have is a Portfolio. In this section the most outstanding works are generally shown, becoming a showcase of our potential.

As well as having a Portfolio full of good works that endorse our performance, the design and functionality of it helps a lot to impress a potential client. For this reason, many of us choose to develop unique Portfolios, with amazing designs and great functionality.

Without further ado, in this tutorial we invite you to develop this elegant and functional Portfolio to get the attention of your potential clients:

The original design belongs to Francesco Zagami, and is published in Dribbble.

If you follow this tutorial, you will see that it is not very complicated to achieve, especially thanks to the MomentumSlider library, which we already introduced in a previous tutorial. It is highly recommended that you take a look at that tutorial, since that explains the basics about this library.

Let’s start!

Planning

Before launching ourselves to develop the design, we must think about how we are going to carry it out, always taking into account the technology that we have available.

In this case, carefully observing the design, we can see that the Portfolio Carousel is composed of 4 independent sliders (images, numbers, titles and links), but synchronized.

With this in mind, we can use the MomentumSlider library without problems, since it allows synchronizing one or several sliders to a main slider. The images could be taken as the main slider, and synchronize the others (numbers, titles and links).

The particularities of each slider are also compatible with our library, so we can start the development!

HTML Structure

Our HTML code will be minimal this time. This is because all the sliders will be generated from JavaScript with the help of the MomentumSlider library. Therefore, our markup will be very simple:

<!-- Container for all sliders, and pagination -->
<main class="sliders-container">
    <!-- Here will be injected sliders for images, numbers, titles and links -->
</main>

Please note that we have not included the rest of the decorative elements that you will see in the final demo, in order to focus on the Portfolio code. In the same way, we will not include the CSS code corresponding to these decorative elements, which undoubtedly will make this tutorial more understandable and easier to follow.

In any case, you can always check the complete code in the Github repository.

Adding styles using the new MomentumSlider mixin

Even before we have our sliders in the HTML (because they will be generated dynamically with Javascript), we can already define some styles for them. This will be very easy if we use the new SCSS mixin offered by the MomentumSlider library.

The SCSS mixin to generate the basic CSS styles of any slider created with MomentumSlider, can be found in the path scss/_ms-mixin.scss, and can receive the following parameters:

  • $cssClass: CSS class to match the slider container.
  • $slider-length: Length (width or height) of slider container.
  • $slider-center: If slider should be centered.
  • $slide-width: Fixed width for each slide.
  • $slide-height: Fixed height for each slide.
  • $vertical: If slider should be vertical (true), or horizontal (false).
  • $reverse: If slider should have reversed slides (first items at the end).
  • $debug: Show helpful background colors to help debugging.

And a simple example, using the default values, would be the following:

@import "ms-mixin";

@include ms(
  $cssClass: 'ms-container',
  $slider-length: 400px,
  $slider-center: false,
  $slide-width: 90px,
  $slide-height: 90px,
  $vertical: false,
  $reverse: false,
  $debug: false
);

Of course, all parameters are optional, using the previous values by default.

As you can see, with this mixin it is very easy to give style to our sliders. Let’s see what the SCSS code for our main slider (images) would look like:

@import "ms-mixin";

// Images

$ms-images-slide-width: 700px;
$ms-images-slide-height: 400px;

// Using SCSS mixin to generate the final CSS code for the slider
@include ms(
  $cssClass: 'ms--images', // CSS class to match the slider container
  $slider-length: 100%,    // The slider container will have full width
  $slider-center: false,   // Don't need to center it, as it is full width
  $slide-width: $ms-images-slide-width,   // Fixed width for each slide
  $slide-height: $ms-images-slide-height, // Fixed height for each slide
  $vertical: false, // The slider should be horizontal
  $reverse: false,  // Normal order
  $debug: false     // No debbug backgrounds in production
);

Maybe you have noticed that there are several unnecessary parameters, since they are equal to the default values. However, writing all parameters is recommended to avoid confusion, or to be constantly consulting the mixin code.

Also keep in mind that at the beginning, to define the position and dimensions of our slider, it is advisable to define the parameter $debug: true, because this will generate very useful background colors for each element of our slider.

Initializing the slider with Javascript

With all the basic styles defined, we can initialize our main slider (for the images) as follows:

// Initializing the images slider
var msImages = new MomentumSlider({
    // Element to append the slider
    el: '.sliders-container',
    // CSS class to reference the slider
    cssClass: 'ms--images',
    // Generate the 4 slides required
    range: [0, 3],
    rangeContent: function () {
        return '<div class="ms-slide__image-container"><div class="ms-slide__image"></div></div>';
    },
    // Syncronize the other sliders
    sync: [msNumbers, msTitles, msLinks],
    // Styles to interpolate as we move the slider
    style: {
        '.ms-slide__image': {
            transform: [{scale: [1.5, 1]}]
        }
    }
});

This code will be quite easy to understand, especially if you followed the previous tutorial on the MomentumSlider library.

As you can see, the sync parameter receives an Array with instances of other sliders that we want to synchronize with the new slider we are creating. Obviously, you must have previously initialized those sliders.

In order to focus on the new functionalities of MomentumSliders, we will not detail the code needed to initialize the other sliders, since it is quite similar to what we have already seen. Anyway, in case of any doubt you can consult the full code in Github.

Customizing styles

Having the images slider working properly, we can add the other styles needed to make our Portfolio Carousel look like the original design:

// Custom styles for images slider
.ms--images {
  left: calc(50% - #{$ms-images-slide-width / 2 - 70px});

  &.ms-container--horizontal .ms-track {
    left: -70px;
  }

  // Slides images
  .ms-slide {
    &:nth-child(1) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/harvey-gibson-498362-unsplash.jpg');
    }
    &:nth-child(2) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/andre-hunter-461305-unsplash.jpg');
    }
    &:nth-child(3) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/joanna-nix-389128-unsplash.jpg');
    }
    &:nth-child(4) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/jurica-koletic-321003-unsplash.jpg');
    }
  }

  .ms-slide__image-container {
    width: 80%;
    height: 80%;
    background-color: rgba(0, 0, 0, 0.3);
    overflow: hidden;
  }

  .ms-slide__image {
    width: 100%;
    height: 100%;
    background-size: cover;
  }
}

One of the main advantages of MomentumSlider is that it allows us to modify the CSS styles of our slider according to our needs without affecting its functionalities. We can add styles of all kinds, as long as we take care not to overwrite the dimensions of the slides.

Adding pagination

The library offers several functionalities out of the box, but if we want a pagination component we must implement it ourselves. However, this is very simple, as we will describe next.

This will be the HTML code that we will use, just one element for each slide:

<!-- Simple pagination for the slider -->
<ul class="pagination">
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>
</ul>

In this case we will not detail the CSS code needed to make our pagination component looks like the design. Instead, let’s look at the Javascrip code to make it works properly:

// Get pagination items
var pagination = document.querySelector('.pagination');
var paginationItems = [].slice.call(pagination.children);

// Update initialization for images slider
var msImages = new MomentumSlider({
    // MORE OPTIONS

    // Update pagination if slider change
    change: function(newIndex, oldIndex) {
        if (typeof oldIndex !== 'undefined') {
            paginationItems[oldIndex].classList.remove('pagination__item--active');
        }
        paginationItems[newIndex].classList.add('pagination__item--active');
    }
});

// Select corresponding slider item when a pagination button is clicked
pagination.addEventListener('click', function(e) {
    if (e.target.matches('.pagination__button')) {
        var index = paginationItems.indexOf(e.target.parentNode);
        msImages.select(index);
    }
});

As you have seen, adding a pagination component is relatively easy, thanks to the features offered by the library.

Making it responsive

Making our Portfolio Carousel looks great on small screens is not such a complex task neither. We just have to fix some positions and solve some minor issues:

// Responsive styles

@media screen and (max-width: 860px) {
  .ms--numbers {
    left: calc(50% - #{$ms-numbers-slide-width / 2});
  }

  .ms--titles {
    left: calc(50% - #{$ms-titles-slide-width / 2});
    top: calc(50% - #{$ms-titles-slide-height / 2 + 50px});
    text-align: center;
  }

  .ms--links {
    left: calc(50% - #{$ms-links-slide-width / 2});
    top: calc(50% + #{$ms-links-slide-height / 2 + 50px});
  }

  .pagination {
    left: 50%;
    top: calc(100% - 50px);
    transform: translateX(-50%);
  }
}

@media screen and (max-width: 600px) {
  .ms--images {
    overflow: visible;
  }
}

@media screen and (max-width: 400px) {
  .ms--titles {
    .ms-slide {
      transform: scale(0.8);
    }
  }
}

That’s it, now our Portfolio Carousel looks great on screens of any size.

Conclusion

And that is all! During this tutorial we have seen the essential elements to create an elegant Portfolio Carousel.

You can see the final result, as well as the Codepen demo. Also, remember that you can check the complete code in the Github repository, where you can see all the details.

We hope you get a lot out of the MomentumSlider library, which we will continue improving to allow us to create even more amazing sliders 🙂

Happy coding!

Source:: scotch.io