Categories
JavaScript Nodejs

How to Use Sequelize to Manipulate Databases

Sequelize is a Node.js ORM with which has one of the most comprehensive features sets available.

It is similar to other ORMs like ActiveRecord, in that they are based on creating migrations with the Sequelize CLI, allowing you to write code to modify your database’s structure.

However, there are a few catches which someone has to be aware of. The migration functionality is not as smart as ActiveRecord. You cannot roll back database migration withour creating a down migration.

Also, migrations are not transactions, which means it may fail with a partially run migration where some parts of it failed to execute, leaving you with some changes made, but others not.

Sequelize CLI has to be installed separately from the library. You can run npm run --save-dev sequelize-cli to install it. After that, run npx sequelize model:generate to create your first model with its associated migration.

Add Model with Migration

For example, to create a User model with a Users table, run:

$ npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string

You may have to have administrator privileges in Windows to run this. This will create a firstName field, a lastName field, and an email field in the User model and when npx sequelize-cli migration is run, then a Users table will be created with the columns firstName , lastName and email .

The migration file should have this code:

'use strict';

module.exports = {  
  up: (queryInterface, Sequelize) => {  
    return queryInterface.createTable('Users', {  
      id: {   
        allowNull: false,  
        autoIncrement: true,  
        primaryKey: true,  
        type: Sequelize.INTEGER  
      },  
      firstName: {  
        type: Sequelize.STRING  
      },  
      email: {  
        type: Sequelize.STRING  
      },  
    });  
   }, down: (queryInterface, Sequelize) => {  
     return queryInterface.dropTable('Users');  
   }  
};

Note the id column is created automatically, and there is a down migration in the down function where the reverse of the up migration is included. If the code in the down function is not included, then you cannot run npx sequelize-cli db:migrate:undo to undo your migration.

You can also create migration and model files separately. They will be linked together if they are named in the correct pattern. Table name should be plural of the model name. For example Users table will map to the User model. To create migration without its associated mode, run npx sequelize migration:generate .

If you have multiple operations, you have to wrap them in an array and pass the array of operations into Promise.all and return that, since the return value of the up and down functions is a promise.

Adding Constraints

Adding constraints is simple. To do this, put the following in the up function of your migration file.

queryInterface.addConstraint(  
  "Users",  
  \["email"\],  
  {  
    type: "unique",  
    name: "emailUnique"  
})

To drop this, put:

queryInterface.removeConstraint(  
  'Users',  
  'emailUnique'  
)

Associations

To make has one, has many or many to many relations between tables, you can specify that using the Model.associate function. For example, if you have a Tweets table where multiple Tweets belong to one User , you can do:

Tweet.associate = function (models) { Tweet.belongsTo(models.User, {  
    foreignKey: 'userId',  
    targetKey: 'id'  
  });  
};

foreignKey is the ID referencing the external table and targetKey is the ID column of the table you’re referencing.

And in the User model:

User.associate = function (models) {  
  User.hasMany(models.Tweet, {  
    foreignKey: 'userId',  
    sourceKey: 'id'  
  });  
};

foreignKey is the ID referencing the current table in this case and sourceKey is the ID column of the table you’re referencing.

This specifies that each User has many Tweets.

Similarly, you can replace hasMany with hasOne to specifiy one to one relationship.

To make a many to many relationship, you need a join table between the 2 tables that you want to create relationship with, then you can use belongsToMany function of your model to create the relationship. You need this in both of your tables that you are creating the relationship with.

For example if multiple Users can belong in multiple ChatRooms , then do:

User.associate = function(models) {        
  User.belongsToMany(models.ChatRoom, {      
    through: 'UserChatRooms',      
    as: 'chatrooms',      
    foreignKey: 'userId',      
    otherKey: 'chatRoomId'    
  });  
};

And for the ChatRoom model:

ChatRoom.associate = function(models) {        
  ChatRoom.belongsToMany(models.User, {      
    through: 'UserChatRooms',      
    as: 'users',      
    foreignKey: 'chatRoomId',      
    otherKey: 'userId'    
  });  
};

foreingKey is the ID that the other table references, otherKey is the key that is in the current table.

Changing Columns

You can rename a column like this:

queryInterface.renameColumn('Tweets', 'content', 'contents')

The first argument is the table name, second is the original column, third one is the new column name.

Changing data type is simple:

queryInterface.changeColumn(   
  'Tweets',  
  'scheduleDate', {  
    type: Sequelize.STRING  
  }  
)

If you want to change string to date or time, do:

queryInterface.changeColumn(  
  'Tweets',   
  'scheduleDate', {  
    type: 'DATE USING CAST("scheduleDate" as DATE)'  
  }  
)queryInterface.changeColumn(  
  'Tweets',  
  'scheduleTime', {  
     type: 'TIME USING CAST("scheduleTime" as TIME)'  
  }  
)

To run migrations, run npx sequelize db:migrate .

And there we have it — a brief look into how to use Sequelize to manipulate databases! 🎉

Categories
JavaScript JavaScript Basics

How to Round Numbers in JavaScript

JavaScript has multiple ways to round a number. Some choices are the Math.round , number.toFixed , andnumber.toPrecision . You can also write your own function to round a number up or down to the nearest increment.

Math.round

Math.round rounds a number to the nearest integer. If the decimal part of the number is less than 0.5, it is rounded down. Otherwise, if the decimal part of the number of 0.5 or higher then it will be rounded up. The function returns the rounded number as the value.

For example:

Math.round(12.5); // 13  
Math.round(12.49); // 12

Number.toFixed

You can set the number of digits that appears after the decimal place with toFixed function. The function returns the string representation of the number as the value. It can be used like this:

const a = 12.8888888888;  
const b = a.toFixed(2); // 12.88

Number.toPrecision

Number.toPrecision is similar to toFixed . It returns the string representation of a number, but you can round it to the specified number of significant digits which you can specify or let it automatically round to the correct number of significant digits.

const a = 12.8888888888;  
const b = a.toPrecision(2); // 13, since 2 significant digits is specified  
const c = a.toPrecision(); // 12.8888888888, since all digits are significant in the original number

Round to the nearest Increment

You can round to the nearest increment up or down you specify:

const roundNumberUp = (num, increment) => {   
  return Math.ceil(num / increment) \* increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is take the original number, divide by the increment you want to round up to, then take the ceiling of that, then multiply by the increment. This means the number should always round up.

Similarly, you can round down to the nearest increment with floor.

const roundNumberUp = (num, increment) => {   
  return Math.floor(num / increment) \* increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is take the original number, divide by the increment you want to round up to, then take the floor of that, then multiply by the increment. This means the number should always round down.

Categories
JavaScript

How to Manipulate and Iterate Arrays in JavaScript

Iterating Array

For Loop

The for loop is one of the most basic loops for looping through an array. It takes a starting index and then loops through to the ending index. Index must be an integer.

Example:

const array = [1,2,3];  
for (let i = 0; i < array.length; i++){  
  console.log(i);  
}

The loop above should log all the numbers in the array.

Indexes do not have to be consecutive:

const array = [1,2,3];  
for (let i = 0; i < array.length; i+=2){  
  console.log(i);  
}

The loop above will skip every second number.

While Loop

while loop will loop whenever a condition stays true.

For example, the loop below will run if the index number i is less than three:

const array = [1,2,3];
let i = 0;  
while(i < array.length){  
  console.log(i);  
}

If the condition in the parentheses is never true, then the loop content will never run.

Do While Loop

do...while loop will always execute the first iteration.

const array = [1,2,3];let i = 0;  
do{  
  console.log(i);  
}  
while(i < array.length)

In the example above, it will at least log 0, but it will also log 1 and 2 in this case since those two numbers are less than three.

With the above loops, you can call break to stop the loop or return before the loop is completely finished.

//do while loop  
const array = [1,2,3];
let i = 0;
do{  
  console.log(i); 
  if (i == 1}{ break; }
}  
while(i < array.length)

//while loop  
i = 0;
while(i < array.length){ 
  if (i == 1){ break; }  
  console.log(i);  
}

//for loop  
for (let j = 0; j < array.length; j++){ 
  if (j == 1){  
    break;  
  }  
  console.log(j);  
}

In the above examples, you will not see two logged.

An example of returning from within the loop:

const loop = ()=>{  
  const array = [1,2,3]; 
  for (let j = 0; j < array.length; j++){ 
    if (j == 1){  
      return j;  
    }  
    console.log(j);  
  }  
}  
loop() //returns 1

You can also skip iterations with continue statement:

const array = [1,2,3];  
for (let j = 0; j < array.length; j++){ 
  if (j == 1){  
    continue;  
  }  
  console.log(j) // 1 will be skipped;  
}

Array.forEach

forEach will iterate through every entry of the array. You cannot break out of it or return a value from it. It takes a callback function where you can execute code.

Example:

const array = [1,2,3];  
array.forEach(a =>{ console.log(a);  
})

In the above example, all the numbers in the array will be logged.


Find Element in Array

Array.find

Array.find will return the element in the array with the given condition. For example, if you want to get certain numbers from the array, you do:

const array = [1,2,3];  
const num = array.find(a => a == 2); // returns 2

find returns a single result.

Array.findIndex

Array.findIndex will return the index of the element in the array with the given condition. It takes a callback function that returns a given condition. For example, if you want to get the index of a certain numbers from the array, you do:

const array = [1,2,3];  
const num = array.findIndex(a => a == 2); // returns 1

Array.filter

Array.filter will return an array of items that meet the given condition. It takes a callback function that returns a given condition. filter returns a new array.

For example, if you want to get the index of a certain numbers from the array, you do:

const array = [1,2,3];  
const numArray = array.filter(a => a == 2); // returns [2]

Check if Element Exists in Array

Array.includes

Array.includes checks if an item exists in an array. It takes a number or string which the function can compare.

const array = [1,2,3];  
const includesTwo = array.includes(2); // returns true

Array.some

Array.somechecks if some items meet the condition given. It takes a callback function which returns a boolean for the condition.

const array = \[1,2,3\];  
const includesTwo = array.some(a => a == 2); // returns true  
const includesFive = array.some(a => a == 5); // returns false

Array.every

Array.every checks if every item meet the condition given. It takes a callback function which returns a boolean for the condition.

const array = [1,2,3];  
const everyElementIsTwo = array.every(a => a == 2); // returns false  
const everyElementIsNumber = array.every(a => typeof a == 'number'); // returns true since every item in the array is a number

Check If an Object Is an Array

Array.isArray

Array.isArray checks if an object given is an array. It is a convenient way to check if an element is an array.

const array = [1,2,3];
const notArray = {};  
let objIsArray = Array.isArray(array); // true  
objIsArray = Array.isArray(notArray); // false

Remove Duplicates in Array

Array.from(new Set(array))

Set is a object that cannot have duplicate entries. You can create a new Set from an array then convert it back to an array.

const array = [1,2,2,3];  
const arrayWithDups = Array.from(new Set(array)); //returns new array without duplicates, [1,2,3]
Categories
JavaScript Nodejs

How to Incorporate Twitter Functionality into Your Node.js App

If you incorporated Twitter sign in functionality according to https://medium.com/@hohanga/how-to-add-twitter-sign-in-to-your-node-js-back-end-with-angular-app-as-the-front-end-d90213f95703, then it is very easy to incorporate Twitter functionality into your app by calling the Twitter API. To get the consumer key and secret, and find out how to get the OAuth access token and secret from Twitter which you will use with the Twitter API, follow https://medium.com/@hohanga/how-to-add-twitter-sign-in-to-your-node-js-back-end-with-angular-app-as-the-front-end-d90213f95703

Once you have the OAuth access token and secret, calling Twitter API is a piece of cake. For Node.js, I had success with https://www.npmjs.com/package/twit.

You simply pass in whatever credentials are requested to build the Twit object, which allows you to call the Twitter API.

Once that is done, you can do many things which otherwise has to be done manually.

According to https://www.npmjs.com/package/twit, here are the endpoints that it can call:

  • GET ‘statuses/update’
  • GET ‘search/tweets’
  • GET ‘followers/ids’
  • GET ‘account/verify_credentials’
  • POST ‘statuses/retweet/:id’
  • POST ‘statuses/destroy/:id’
  • GET ‘users/suggestions/:slug’
  • POST ‘media/upload’
  • ‘media/metadata/create’
  • ‘statuses/filter’

All the basic functionality like tweeting, uploading photos, and streaming can be used with this library, which means that you can automate tweeting and getting data from your account.

The full list of endpoints are at https://developer.twitter.com/en.html

Categories
JavaScript JavaScript Basics

How To Do Common JavaScript Object Operations

Define New Object Literal

You can define object literals in JavaScript. An object does not have to an instance of a class in JavaScript.

You can define it like this:

const obj = { chicken: { hasWings: true }}

Define Object with Constructor

JavaScript lets you define objects that can be instantiated like a class with the new keyword.

You can define it like this:

const bird = function(hasWings){ this.hasWings = hasWings;}const chicken = new bird(true);  
console.log(chicken.hasWings); // true

Note the use of the function keyword instead of an arrow function. It is required to set this’s scope to the function itself.

Since ES6, you can define an object as an instance of a class.

For example:

class bird{  
  constructor(hasWings){  
    this.hasWings = hasWings;  
  }  
}const chicken = new bird(true);  
console.log(chicken.hasWings); // true

Get Keys of Object

Object.keys can be used to get all the top level keys of an object as strings. For example:

const chicken = { hasWings: true, bodyParts: [ {head: 1} ]};  
console.log(Object.keys(chicken)) // ['hasWings', 'bodyParts'];

Get Entries of an Object

Object.entriescan be used to get all the top level keys value entries of an object as arrays. For example:

const chicken = { hasWings: true, bodyParts: ['head', 'tail']};  
console.log(Object.entries(chicken)) // [['hasWings', true], ['bodyParts', ['head', 'tail']]];

Merge Two Objects

We can use the spread operation to combine two objects into one.

const a = {foo: 1};  
const b = {bar: 1};  
const c = {...a, ...b}; // {foo: 1, bar: 1}

If two objects have the same keys, the value of the one that is merged in last will override the earlier one.

const a = {foo: 1};  
const b = {bar: 1};  
const c = {bar: 2};  
const d = {...a, ...b, ...c};   
console.log(d) // {foo: 1, bar: 2}

Prevent Modification to an Existing Object

Object.freeze can be used to prevent an object from being modified. freeze takes an object as its argument and freezes an object in place.

For example:

let a = {foo: 1};  
a.foo = 2;  
Object.freeze(a);  
a.foo = 3;  
console.log(a) // {foo: 2}

Check If an Object Can Be Modified

Object.isFrozen can be used to check if an object is frozen by Object.freeze .

For example:

let a = {foo: 1};  
a.foo = 2;  
Object.freeze(a);  
a.foo = 3;  
console.log(Object.isFrozen(a)) // true

Clone Objects

If you assign an 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 an 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

That’s it—a few simple steps for a few simple operations!