Categories
JavaScript JavaScript Basics

How to Copy Objects in JavaScript

Copying objects means making a new object reference to an object that has the same contents as the original. It is used a lot to prevent modifying the original data while you assign a variable to another variable. Because if you assign a variable to a new one, the new one has the same reference as the original object.

There are a few ways to clone objects with JavaScript. Some functions do shallow copying which means that not all levels of the object are copied, so they may still hold the reference the original object. A deep copy copies everything so that nothing references the original object, eliminating any confusion which arises from shallow copy.

Clone Object Using Built in JavaScript Functions

Is you assign a object to another variable, it just assigns the reference to the original object, so both variables will point to the original object. When one of the variables are manipulated, both will be updated. This is not always the desired behavior. To avoid this, you need to copy a object from one variable to another.

In JavaScript, this is easy to do. To shallow copy an object, we can use Objec.assign() , which is built into the latest versions of JavaScript. This function does a shallow copy, which means it only copies the top level of an object, while the deeper levels remain linked to the original object reference. This may not be desired if there is nested in your original object.

Here is an example of how to use Object.assign :

const a = { foo: {bar: 1 }}  
const b = Object.assign({}, a) // get a clone of a which you can change with out modifying a itself

You can also clone an array like this:

const a = \[1,2,3\]  
const b = Object.assign(\[\], a) // get a clone of a which you can change with out modifying a itself

To do a deep copy of a object without a library, you can JSON.stringify then JSON.parse :

const a = { foo: {bar: 1, {baz: 2}}  
const b = JSON.parse(JSON.strinfy(a)) // get a clone of a which you can change with out modifying a itself

This does a deep copy of an object, which means all levels of an object are cloned instead of referencing the original object.

JSON.parse and JSON.stringify only works with plain objects, which means it cannot have functions and other code that runs.

With ES6, you can also use object destructuring to shallow clone objects, like so:

const a = { foo: {bar: 1}}  
const b = {...a} // get a clone of a which you can change with out modifying a itself

Clone Object Using Third Party Libraries

There are many third parties which can do the same things. Lodash has _.clone and _.cloneDeep functions for shallow and deep copy. Underscore has a _.clone function for shallow copy.

Cloning objects is common operation that is easy to do with JavaScript. Now you can avoid bugs by not modifying objects that you are not intending to modify by copying them and then modify the copied object.

Categories
JavaScript JavaScript Basics

How to Check if a JavaScript Object is an Array

There are a few simple ways to check if an object is an array.

Array.isArray

The simplest and easiest way is to use Array.isArray , which are available in most recent browsers, IE9+, Chrome, Edge, Firefox 4+, etc. It is also built into all versions of Node.js. It checks whether any object or undefined is an array.

To use it, do the following:

const arr = [1,2,3,4,5];
const isArrAnArray = Array.isArray(arr); // true

const obj = {};
const isObjAnArray = Array.isArray(obj); // false

const undef = undefined;
const isUndefinedAnArray = Array.isArray(undef); // false

Alternatives

Alternatives include using instanceOf , checking if the constructor is an array or checking if an object’s prototype has the word Array.

Using instanceOf , you can do:

const arr = [1,2,3,4,5];
  const isArray = (arr)=>{
    return arr.constructor.toString().indexOf("Array") > -1;
  }
  console.log(isArray(arr)) // true

Similarly, by checking an object’s prototype, you can do:

const arr = [1,2,3,4,5];
const isArray = (arr) => {
  return Object.prototype.toString.call(arr) === '[object Array]';
}
console.log(isArray(arr)) // true

Third Party Libraries

Underscore and Lodash also have equivalent array check functions:

const arr = [1,2,3,4,5];
const isArraAnArray _.isArray(arr); // true
Categories
JavaScript Nodejs

How to Add Twitter Sign In to Your Node.js Back End

Twitter uses the standard OAuth for authentication, which means you incorporate a standardized way of logging in if you use Twitter sign in.

In Node.js, it is very easy to add Twitter sign in to an Express web app.


Getting Started

First, you have to make an Express app. Express is a routing library with a lot of add-ons built for easy web development.

There are many Express app boilerplates available on the web. There is also an Express code generator from the makers of the Express framework.

Using the latest Node.js versions, you can run npx express-generator.

If npx is not available, you can install express-generator globally and run that:

$ npm install -g express-generator  
$ express

Make a folder for your project and follow the instructions.

To make the example simple, this app will provide the redirect URL that you get after providing the consumer key and request token for the Angular app.

Then, after the user goes through the Twitter sign in, it will redirect back to the Angular app, which will then call the Express API to save the OAuth access token and the OAuth access token secret to a database.

We need to make an entry point file for Express.

We need to install express-session, express-logger, cookie-parser, and cors for saving sessions, logging, parsing cookies, and allowing external requests for our Angular app, respectively.

babel-register and bale-polyfill are required to use the latest JavaScript features in our Node.js web app.

To save the secrets, use the [dotenv](https://www.npmjs.com/package/dotenv) library. With this, the secrets will be read from the .env file, rather than hard coding them into the code, which is very bad secret practice.

To get the Twitter keys, you have to apply for a developer account at https://developer.twitter.com/. You will then get the keys and secrets required, which you will put into the .env file.

The .env file should be a key-value list, like this:

TWITTER_CONSUMER_KEY=''  
TWITTER_CONSUMER_SECRET=''  
TWITTER_CALLBACK_URL='http://localhost:4200/settings'
SESSION_SECRET=''

I will call the entry point file app.js .

To run this, go to your project folder and run node app.js:

Then, we need the oauth library to make an oauth.OAuth object which will allow the Express app to get the request token and request token secret.

Add a controllers folder in the same level as app.js.

Then, add sessionsController.js into the controllers folder.

Add the following to sessionsController.js:

The connect route will send the Twitter sign-in URL as the redirect URL.

Then, the Angular app will call the saveAccessTokens route to store the OAuth access token and its secret in the session.


Angular CLI

To build the Angular app, you need the Angular CLI.

To install it, run npm i -g @angular/cli in your Node.js command prompt. Then, run ng new frontend to generate the skeleton code for your front end app.

Also, install @angular/material according to the Angular documentation.

After that, replace the default app.module.ts with the following:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
  MatButtonModule,
  MatTableModule,
  MAT_DIALOG_DEFAULT_OPTIONS,
} from '@angular/material';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SettingsPageComponent } from './settings-page/settings-page.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { SessionService } from './session.service';
import { HttpReqInterceptor } from './http-req-interceptor';
@NgModule({
  declarations: [
    AppComponent,
    SettingsPageComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatButtonModule,
    FormsModule,
    HttpClientModule,
  ],
  providers: [
    SessionService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpReqInterceptor,
      multi: true
    },
    UserService,
    TweetsService,
  ],
  bootstrap: [AppComponent],
})
export class AppModule { }

We need to use Angular’s HTTP client to connect to our Express routes to get the redirect URL and get the access token from the redirect after logging in with Twitter, then send it back to our route.

To do this, run ng g service session.

This will create session.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
@Injectable({
  providedIn: 'root'
})
export class SessionService {
  constructor(private http: HttpClient) { }
  getRedirectUrl() {
  return this.http.get(`${environment.apiUrl}/sessions/connect`)
}
  saveAccessToken(oauthToken: string, oauthVerifier: string) {
    return this.http.get(`${environment.apiUrl}/sessions/saveAccessTokens?oauth_token=${oauthToken}&oauth_verifier=${oauthVerifier}`)
  }
}

In here, environment.apiUrl is the URL to our API, which is specified in environment.ts.

Now, we need a page with a button that calls our Express route to get the redirect URL.

Run ng g component settingsPage to create settings-page.component.ts and settings-page.component.html, which is where the button will be placed.

Add the following to settings-page.component.html:

<div>  
  <button mat-raised-button (click)='redirectToTwitter()'>Connect to Twitter Account</button>  
</div>

Then, add the following settings-page.component.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SessionService } from '../session.service';
@Component({
  selector: 'app-settings-page',
  templateUrl: './settings-page.component.html',
  styleUrls: ['./settings-page.component.scss']
})
export class SettingsPageComponent implements OnInit {
  constructor(
    private activatedRoute: ActivatedRoute,
    private sessionService: SessionService,
  ) {
    this.activatedRoute.queryParams.subscribe(params => {
      const oauthVerifier = params['oauth_verifier'];
      const oauthToken = params['oauth_token'];
      if (oauthToken && oauthVerifier) {
        this.saveAccessToken(oauthToken, oauthVerifier);
      }
    });
  }
  ngOnInit() {}
  saveAccessToken(oauthToken: string, oauthVerifier: string) {
    this.sessionService.saveAccessToken(oauthToken, oauthVerifier).subscribe(res => {
    alert('Token saved');
    })
  }
  redirectToTwitter() {
    this.sessionService.getRedirectUrl().subscribe((res: any) => {
      location.href = res.redirectUrl;
    })
  }
}

After adding the code above, you get a button that, after you click it, will go to the Twitter sign-in page.

Then, once Twitter sign in succeeds, you will be redirected to the same page with the OAuth access token and verifier, which will be sent to our Express API and stored in the session.


Token Saved

You will get Token saved message once it succeeds.

In the end, this is the workflow you should get:

  1. First, you get the connect button:

https://thewebdev.info/wp-content/uploads/2020/05/connect.png

  1. Then, you are redirected to the Twitter login:

https://thewebdev.info/wp-content/uploads/2020/05/twitter-login.png

  1. Finally, you are redirected back with the OAuth access token and verifier, and with those, you get the access token and secret which will be stored to the session.

If that succeeds, the saveAccessTokens route will return a successful response, which will then trigger the Angular app to alert Token saved.

Categories
JavaScript TypeScript

Introduction to TypeScript Classes — Static Properties, Abstract Classes and More

Classes in TypeScript, as in JavaScript, are a special syntax for its prototypical inheritance model that’s a comparable inheritance in class-based object oriented languages. Classes are just special functions added to ES6 that are meant to mimic the class keyword from these other languages.

In JavaScript, we can have class declarations and class expressions because they’re just functions. So like all other functions, there are function declarations and function expressions. This is the same with TypeScript. Classes serve as templates to create new objects. TypeScript extends the syntax of classes of JavaScript and then adds its own twist to it. In this piece, we’ll look at static properties, abstract classes, and constructor functions.


Static Properties

With TypeScript, we can designate members as instance variables, which don’t have the keyword static before them, and static members, which have the keyword static keyword before them.

Static members can be accessed without having the class instantiated. Of course, this is given to the access modifiers that are designated for the member. So public static members can be accessed directly from outside the class. Private static members can only be used within the class, and protected members can be accessed by a class the member is defined in and also by subclasses of that class.

The static keyword can be used by both fields and methods. For example, we can use it like in the following code:

class Person {  
  static numPeople = 0;    
  constructor(name: string) {  
    Person.numPeople++;  
  }  
  static getNumPeople() {  
    return this.numPeople;  
  }  
}

const john = new Person('John');  
const jane = new Person('Jane');  
console.log(Person.numPeople);  
console.log(Person.getNumPeople());

In the code above, every time we instantiate the Person class, we increase the static property numPeople by one. Since static properties are shared by all instances of the class and don’t belong to any one instance, we can access numPeople directly by using Person.numPeople.

Likewise, we have a static method, getNumPeople, we can call directly without instantiating the Person class. Therefore, when we get the numPeople by using Person.numPeople and call the Person.getNumPeople(), then the value 2 is returned for both.

Since the members are static, the values is part of a class and not part of any instance, so even if the instances are destroyed the values will be kept. This is different from instance variables, which are accessed from the this inside the class and the variable with the instance of the class outside the class.


Abstract Classes

TypeScript has abstract classes, which are classes that have partial implementation of a class and in which other classes can be derived from. They can’t be instantiated directly.

Unlike interfaces, abstract classes can have implementation details for their members. To declare an abstract class, we can use the abstract keyword. We can also use the abstract keyword for methods to declare abstract methods, which are implemented by classes that derive from an abstract class.

Abstract methods don’t contain implementations of the method. It’s up to the subclasses that derive from the abstract class to implement the method listed. They may also, optionally, include access modifiers.

We can use abstract classes and methods as demonstrated in the following code:

abstract class Person {  
  name: string;  
  age: number;  
  constructor(name: string, age: number) {  
    this.name = name;  
    this.age = age;  
  } abstract getName(): string;  
  abstract getAge(): number;  
}

class Employee extends Person{  
  constructor(name: string, age: number) {  
    super(name, age);  
  } 

  getName() {  
    return this.name;  
  } 

  getAge() {  
    return this.age;  
  }  
}

let employee = new Employee('Jane', 20);  
console.log(employee.getName());  
console.log(employee.getAge());

In the code above, we have the abstract Person class, which has the abstract methods getName and getAge.

As we can see, the abstract methods only have signatures in them. The actual implementation of the methods are in the Employee class, which extends the Person class.

We have the actual implementation of the getName and getAge methods in the Employee class.

TypeScript checks the method signature and the return type of the class, so we must be implementing the abstract methods as it’s outlined in the abstract class. This means that in the example above, the getName method must take no parameters and must return a string.

Likewise, the getAge method must take no parameters and must return a number. After the abstract methods have been implemented, we can call them normally like any other method.


Constructor Functions

When we declare a TypeScript, we’re declaring multiple things at the same time. We’re declaring an instance of the class, which is the entity with the code preceded with the class keyword. For example, we can write:

class Employee{  
  name: string;  
  age: number;  
  constructor(name: string, age: number) {  
    this.name = name;  
    this.age = age;  
  }
}  
let employee: Employee = new Employee('Jane', 20);

In the last line of the code snippet above, we’re using Employee as the type of the instances of the class Employee.

Also, we’re creating another value we call a constructor function. This is the function that’s called when the new keyword is being used to create a new instance of the class.

If we compile the TypeScript code above to ES5 or earlier, we can see we get something like the following code generated:

"use strict";  
var Employee = /** @class (function () {  
    function Employee(name, age) {  
        this.name = name;  
        this.age = age;  
    }  
    return Employee;  
}());  
var employee = new Employee('Jane', 20);

In the code above, the constructor function is the following code:

function Employee(name, age) {  
  this.name = name;  
  this.age = age;  
}

We have this because in JavaScript, no matter what version we’re using, a class is just the syntactic sugar for constructor functions. The inheritance model of TypeScript just extends from JavaScript. It didn’t change the inheritance model of JavaScript since it’s supposed to be 100% compatible with existing JavaScript code so existing JavaScript code can be adopted to use TypeScript.

In TypeScript, we can get the type of the constructor function with the typeof operator. It’s different from its usage in JavaScript as it has been extended to get the type of the constructor function of a class. If we run the following code …

class Employee{  
  name: string;  
  age: number;  
  static companyName: string = 'ABC Company';  
  constructor(name: string, age: number) {  
    this.name = name;  
    this.age = age;  
  }}

let employeeConstructor: typeof Employee = Employee;  
console.log(Employee.companyName);  
console.log(employeeConstructor.companyName);

… it makes sense when we get the value of the static member companyName logged in both console.log statements. As we can see from the compiled output …

"use strict";  
var Employee = /** @class */ (function () {  
    function Employee(name, age) {  
        this.name = name;  
        this.age = age;  
    }  
    Employee.companyName = 'ABC Company';  
    return Employee;  
}());  
var employeeConstructor = Employee;  
console.log(Employee.companyName);  
console.log(employeeConstructor.companyName);

… a JavaScript and TypeScript class are ultimately just functions. The class syntax makes inheritance of JavaScript easier to use since it looks like it’s using class-based inheritance, but it’s actually syntactic sugar on top of the prototypical inheritance model that’s been the same since JavaScript first came out.

TypeScript makes inheritance easy by letting us define abstract classes — where some implementation is done by the abstract and others are done in the subclass that extends the abstract class.

We also have abstract methods that subclasses can implement. Abstract methods only have the signature and return type and no implementation details.

Static members let us define members that are part of the class rather than an instance of the class.

It’s also important to know that the class syntax is ultimately syntactic sugar for the prototypical inheritance model that existed since the beginning of JavaScript. However, now we can put that aside since we can use the syntactic sugar to make it easier to understand and implement inheritance.

Categories
JavaScript

Why is Lodash Still Useful?

With the release of ES6 and later versions of JavaScript, there were lots of methods released with it, expanding the functionality of the language. For example, there are new array and string methods, as well as useful operators like the spread and rest operators.

However, JavaScript still doesn’t make utility libraries like Lodash obsolete because there are lots of useful methods that still aren’t available in JavaScript.

In this article, we’ll look at a few methods from Lodash that still makes development easier than with plain JavaScript, including the times, get, set, debounce, deburr, and keyBy methods.

_.times

The times method lets us call a function multiple times, put all the retuned results of each function call into an array, and return it.

It takes 2 arguments, which are the number of times that the function is called and the second is the function to call.

For example, we can use it as follows:

import * as _ from "lodash";
const getRandomInteger = () => Math.round(Math.random() * 100);  
let result = _.times(5, getRandomInteger);  
console.log(result);

Then we may get the following result:

[16, 83, 35, 87, 41]

_.debounce

We can use the debounce method to delay a call of a function by a specified amount of time. There’s no easy way to do this with JavaScript.

This is useful for event handling where we want to wait for something to be done and then call a function. For example, with a typeahead search, a debounce would wait until the user is finished typing before making the API call, removing unnecessary hits on your server.

For example, we can use it as follows. Given the following number input:

<input type="number" />

We can write the following JavaScript code:

import * as _ from "lodash";
const checkPositiveNumber = e => {  
  console.log(+e.target.value > 0);  
};

const numInput = document.querySelector("input[type=number]");  
numInput.addEventListener("input", _.debounce(checkPositiveNumber, 600));

The code above has the checkPositiveNumber function that checks if the value entered is positive. Then we use the debounce method, which takes the function and the delay before calling it in milliseconds.

The function returned by debouce has the same parameters and content as the original function, except that it’s delayed by the given number of milliseconds before calling it.

_.get

The get method lets us access the properties of an object in a safe way. That is, even if the path to the properties doesn’t exist, it will return undefined or a default value instead of crashing the program.

For example, given the following object:

const obj = {  
  foo: {  
    bar: { baz: { a: 3 } },  
    foo: { b: 2 },  
    baz: [1, 2, 3]  
  }  
};

We can access obj‘s property as follows:

const result = _.get(obj, "foo.bar.baz.a", 1);

The first argument is the object we want to access a property’s value. The second is the path to the property. The last argument is the default value.

We should get 3 for result.

On the other hand, if the path doesn’t exist or it’s undefined, then we get undefined or a default value returned.

For example, if we have:

const result = _.get(obj, "foo.bar.a", 1);

Then we get 1 for result.

If we don’t specify a default value as follows:

const result = _.get(obj, "foo.bar.a");

Then we get undefined.

There’s no way to safely get the value of a deeply nested property until the optional chaining operator becomes mainstream.

_.set

There’s also a set method to assign a value to a property of an object. For example, given the same object we had before:

const obj = {  
  foo: {  
    bar: { baz: { a: 3 } },  
    foo: { b: 2 },  
    baz: [1, 2, 3]  
  }  
};

We can set a value to a property by writing:

_.set(obj, "foo.bar.a", 1);

The obj object is changed in place. As we can see, it can set values for properties that don’t exist yet. The original object didn’t have foo.bar.a and it added it automatically set the value to 1.

So we get:

{  
  "foo": {  
    "bar": {  
      "baz": {  
        "a": 3  
      },  
      "a": 1  
    },  
    "foo": {  
      "b": 2  
    },  
    "baz": [  
      1,  
      2,  
      3  
    ]  
  }  
}

It even works if the nested object doesn’t exist, so if we write:

_.set(obj, "foo.foofoo.bar.a.b", 1);

We get:

{  
  "foo": {  
    "bar": {  
      "baz": {  
        "a": 3  
      }  
    },  
    "foo": {  
      "b": 2  
    },  
    "baz": [  
      1,  
      2,  
      3  
    ],  
    "foofoo": {  
      "bar": {  
        "a": {  
          "b": 1  
        }  
      }  
    }  
  }  
}

_.deburr

To remove accents from characters with strings, we can use the deburr method. It takes in a string and returns a new string with the characters that have accents replaced with the ones that don’t have them.

For example, if we have “S’il vous plaît”:

const result = _.deburr("S'il vous plaît");

Then we get that result is "S’il vous plait" . The ‘i’ no longer has the accent.

_.keyBy

The keyBy method takes an array and the property name and returns an object with the value of the property as the keys of the object.

For example, if we have the following array:

const people = [  
  { name: "Joe", age: 20 },  
  { name: "Jane", age: 18 },  
  { name: "Mary", age: 20 }  
];

Then we can use keyBy as follows:

const results = _.keyBy(people, "name");

Then results would have the following:

{  
  "Joe": {  
    "name": "Joe",  
    "age": 20  
  },  
  "Jane": {  
    "name": "Jane",  
    "age": 18  
  },  
  "Mary": {  
    "name": "Mary",  
    "age": 20  
  }  
}

Then we get the object with name 'Joe' by writing:

results['Joe']

There’s no way to do this easily with plain JavaScript without writing multiple lines of code.

Conclusion

Lodash has many useful functions that don’t have an equivalent that are as easy to use as these methods.

There’s the times method to call a function multiple times in one line. The debounce function returns a new function with the same signature and code as the original but it’s delayed by the given amount of milliseconds before it’s called.

For accessing and setting object properties and values safely, there are the get and set methods that don’t crash when we access property paths that don’t exist or has value undefined.

Then there’s the deburr method to replace accented characters with the non-accented versions of these characters.

Finally, there’s keyBy method to get massage an array into an object that has the given property’s value of each entry as the keys and the entry with the given property’s name’s values as the value of those keys.