Tag: javascript

Understanding Angular lifecycle methods with Examples

In Angular, components have a lifecycle managed by Angular itself, from creation to destruction. Angular provides lifecycle methods that you can use to tap into this process and perform custom logic at specific points in the lifecycle.

Here are some examples of how you might use each lifecycle method:

ngOnChanges: This method is called whenever a bound input property changes. You can use it to react to changes in input properties and perform logic when the value of an input property changes.

In this example, the CounterComponent implements the ngOnChanges method and logs the changes to its input properties.

  1. ngOnInit: This method is called after the first ngOnChanges call and is used to perform initialization logic for the component.

In this example, the HelloComponent implements the ngOnInit method and initializes its name property.

  1. ngDoCheck: This method is called during every Angular change detection cycle and is used to perform custom change detection.

In this example, the TodoListComponent implements the ngDoCheck method and logs its items array.

  1. ngAfterContentInit: This method is called after the component’s content has been fully initialized.

In this example, the TabsComponent implements the ngAfterContentInit method and logs a message to the console.

  1. ngAfterContentChecked: This method is called after every change detection cycle that updates the component’s content. It can be used to perform logic that depends on the component’s content being fully updated and checked.

In this example, the TabsComponent implements the ngAfterContentChecked method and logs a message to the console.

6. ngAfterViewInit: This method is called after the component’s view (including its child views) has been fully initialized.

In this example, the TabPanelComponent implements the ngAfterViewInit method and logs a message to the console.

7. ngAfterViewChecked: This method is called after every change detection cycle that updates the component’s view (including its child views).

In this example, the TabListComponent implements the ngAfterViewChecked method and logs a message to the console.

8. ngOnDestroy: This method is called just before the component is destroyed by Angular. It can be used to perform cleanup logic for the component, such as unsubscribing from observables or detaching event handlers.

In this example, the TimerComponent implements the ngOnDestroy method and uses it to stop the interval timer it started in its ngOnInit method.

I hope you found this article useful and informative. Thanks ūüėä

Creating a Vue.JS Instance Using its Fundamental Concepts

Vue.js is simple and powerful, and it is easy to learn. Once you understand the basics of the framework, everything will work in just the way you expect. The framework will help you to keep focused on writing the logic of your application instead of remembering a bunch of APIs that are hard to use. This article will help you learn some of the fundamental concepts in Vue.js.

Fundamental concepts

When you start a Vue application, what you need to keep in mind is your application’s logic itself. You don’t need to remember a set of APIs so that you can connect different pieces of your code. Vue.js, which is a progressive framework, provides you with an intuitive way of writing web applications, starting small and growing incrementally into a large-scale application. If you have used other frameworks before, you may wonder why they make things unnecessarily complicated. Now, let’s go through fundamental concepts in Vue.js and create a sample application. You can also access the complete code for this article at https://github.com/PacktPublishing/Building-Applications-with-Spring-5-and-Vue.js-2/tree/master/Chapter02/MessagesApp.

Creating a Vue instance

Creating a Vue instance is the start of every Vue.js application. Typically, a Vue application consists of two types of Vue instance‚ÄĒthe root Vue instance and component instances. You create the root instance with the Vue function, as follows:

The options object here is where you describe your application. Vue.js takes this object and initializes the Vue instance. Let’s create a simple application, called the Messages App and see how to use the options object. This SPA has the following features:

  • Add a message
  • View messages list
  • Delete a message
  • Automatically disable the add feature under certain conditions

We will start by creating the index.html file and, from there; we will build our application incrementally. Let’s have a look at the index.html file:

In line 5, we create a 

 element with an app id in the DOM. And in line 9, we mount our application to this element by using the el property of the options object. el is short for element, and its value can be a CSS selector string, like the one we use here, '#app', or it can be the HTMLElement itself, document.getElementById('app'). In line 8, we assign the Vue instance to the vm variable, which is short for ViewModel.

Now, let’s define our data model of the application. We need an array to hold those added messages and a string to bind to the form’s input which will accept new messages. Here is how the data object appears:

We add the data object using object literals. As you can see, it is quite straightforward. We give them initial values so that you can easily tell that messages is an array and newMessage is a string. Providing initial values for the data object properties is a good practice. It not only helps you understand the data model better, but also makes those properties reactive by default. 

Besides using a plain object as the value of the data property of the options object, you can also use a function that returns a plain object, as in the example:

Using a function is required when you define the data structure for a component because, in that way, Vue.js will always create a fresh data model for the new component. If you use a plain object to define a component’s data model, all of the instances of that component will share the same data object, which is not desired. For our root Vue instance here, we are safe to use a plain object.

For now, we have only defined the data model, and we haven’t told Vue.js what to do with the data object. Let’s add a template for displaying and adding messages. You can add a template in three ways. One is to add an inline template string using the template property of the options object. It is appropriate to adopt this approach when you create a component that doesn’t have a lot of markups.

The second way is to put the template directly inside the mounting point, 

. Vue.js will parse the template inside #app and replace it with HTML generated by Vue.js. The third way is to put the template markup inside a script tag, for example, <script type="x-template" id="tmplApp">, and put '#tmplApp' as the value of the template property of the options object. We will adopt the second approach here just so we can have the template markup close to the final output. Here is how the template appears:

In line 7, we use the Vue built-inv-for directive to render the messages list. The syntax of the v-for directive is alias in source. In our code, message is alias and messages is source. We don’t need to write vm.messages in order to access the messages property. Just use the exact name that you put in the data object. And by adding the v-for directive to the li tag, we create a v-for block inside the li tag, and that’s where thealias message will be available. You can think of the v-for block as being equivalent to the for-loop block in JavaScript.

In line 8, we use Mustache syntax to output the text property and createdAt property of a message object of the messages list. The createdAt property is a Date object that we add when saving a new message. When Vue.js parses the template and interpolates a Mustache tag, for example, {{message.text}}, it creates data binding between the output and the data. It will replace the tag with the actual value and update the output whenever the text property has been changed. The text interpolation also supports JavaScript expression. For example, you can make the text property always in lower case with {{message.text.toLowerCase()}}.

In line 11, we use another built-in directive, v-on, to attach an event listener to the form’s submitevent.prevent is a modifier, telling Vue.js to call event.preventDefault() so that the browser won’t actually submit the form. addMessage is a method that will be invoked when the form’s submit event is triggered. We will create this method shortly. You can use v-on to attach listeners to all of the normal DOM events, for example, click and mouseover. You can also use it to listen to custom events of Vue’s custom components in the same way. We will see how that works shortly.

In line 12, we use the built-inv-model directive to create a two-way binding between the textarea element and newMessage property of the data object. In this way, whenever the value of the textarea element is changed, the newMessage will be updated automatically. And when newMessage is changed, textarea will be updated accordingly. This is such a nice feature that you can get the value of the textarea element without touching it yourself specifically. It works just as you would imagine it should.

In line 14, we add a button with type="submit" to trigger the submit event of the form. Now, let’s create our addMessage method to listen to that event. We can do it by using the methods property of the options object.

Here is how the options object appears with the addMessage method:

The methods property of the options object takes an object, where you put all of your methods. And inside these methods, you have access to the properties of the data object via this, as you can see that we use this.newMessage and this.messages inside the addMessage method to access them. The method syntax we use here is ES6, but you can also use function expression, as follows:

However, you should not use arrow functions syntax to create methods because you will lose access to the Vue instance via this.

Inside the addMessage method, we add the new message to the messages array using the push() method, and then we reset the newMessage property. Accordingly, Vue.js will clear textarea in the UI automatically. This is the magic of two-way binding, which will be revealed soon.

Now, let’s add a way to delete a message from the UI. Here is what we change in the template:

We add a button and use @click, the short-hand of v-on:click, to attach the listener deleteMessage method to the click event. Instead of putting the method’s name here, we use an inline statement to pass the message object to the method. And here are the updated methods of the options object:

We delete the selected message from the messages array using the Array.prototype.splice() method. Vue.js will detect this change and update the DOM automatically. You don’t need to manipulate the DOM at all.

Now, let’s add the ability to automatically disable the add feature. Let’s say we want to disable the Add button when there are 10 messages in the list. To do that, we can use the built-in v-bind directive to bind the Add button’s disabled attribute with the messages.length >= 10 expression. In this way, Vue.js will update the disabled attribute automatically when the length of the messages array changes. Here is the updated template:

What if we want to change the logic so that the Add button is disabled when the length of the textarea input exceeds 50 characters? You will need to change the value of the v-bind directive to newMessage.length > 50. What if we want to disable the button when there are already 10 messages, or the length of newMessage exceeds 50 characters? We can change the directive value to messages.length >= 10 || newMessage.length > 50. It still works. However, as you can see, the code starts to bloat and it would become hard to maintain when you need to add more logic to decide when the Add button should be disabled.

Here, we can use computed properties. As the name suggests, the value of such a property is computed rather than defined as those in the data object. And Vue.js will track the dependencies of a computed property and update the property’s value when the dependencies change. Let’s add the computed property addDisabled to the options object:

As you can see, the addDisabled computed property is defined as a method of the computed object of the options object. Inside the method, you also have access to the Vue instance via this. For the v-bind directive, there is also a shorthand option, which is a colon (:). Let’s update the Add button in the template to the following:

As you can see, our template becomes much easier to follow and maintain since you keep most of the logic in the JavaScript rather than in the HTML template. 

For the v-bind directive, you can use it to bind the HTML element’s built-in attributes, for example, class and style. You can also use it to bind a Vue’s custom component property. We will see how that works shortly.

By now, we have implemented all of the features of the Messages App. Since we didn’t use¬†<script type="module">, you can open¬†index.html¬†directly using Chrome. If you try it now, you will see something strange. Immediately after opening the file, you can see the template markups that we put inside the mounting point,¬†

, which is awkward. The reason that it behaves in this way is that, before the browser loads Vue.js and executes it, it will display the HTML in the manner it is defined until Vue.js takes control of the DOM and removes the template¬†markups¬†from the mounting point and then replaces it with the new dynamically generated DOM. Let’s fix this by adding the v-cloak directive¬†to the mounting point and inserting a CSS rule to hide the template markups. Vue.js will remove the¬†v-clock¬†directive when the generated DOM is ready. The following are the updates to the¬†index.html¬†file:

Besides the [v-cloak] CSS rule, we add a few other rules to style the UI a little bit, even though it is still very primitive with these rules. Now, if you open it again in the browser, there is no flash anymore. 

By now, you’ve learned how to use the data object, the computed object, and the methods object of the options object of a Vue instance. And you can see that, even though the properties of these objects are defined separately, you can access them in the same way, which is via this

Now, let’s open the Console tab of Chrome’s Developer tools. Instead of using the input field in the UI, let’s add a new message from the console by interacting directly with the vm object, which is the root Vue instance that we created and made available in the global scope. As you can see from the following screenshot, it works as you would expect. This is its simplicity and powerfulness:


The Messages App in Chrome

Apart from the datacomputed, and methods properties, the options object has many other properties that you can use to define a Vue instance.

If you found this article interesting, you can explore Building Applications with Spring 5 and Vue.js 2 to Become efficient in both frontend and backend web development with Spring and Vue. With the help of Building Applications with Spring 5 and Vue.js 2 you’ll get to grips with Spring 5 and Vue.js 2 as you learn how to develop a web application.

Using Modules in Node.js

Node.js is an event-driven, server-side JavaScript environment. Node.js runs JS using the V8 engine developed by Google for use in their Chrome web browser. Leveraging V8 allows Node.js to provide a server-side runtime environment that compiles and executes JS at lightning speeds.

The Module System

This article covers the Node’s module system and the different categories of the Node.js modules.

Application Modularization

Like most programming languages, Node.js uses modules as a way of organizing code. The module system allows you to organize your code, hide information, and only expose the public interface of a component using module.exports.

Node.js uses the CommonJS specification for its module system:

  • Each file is its own module, for instance, in the following example, jsand math.js are both modules
  • Each file has access to the current module definition using the modulevariable
  • The export of the current module is determined by the module.exportsvariable
  • To import a module, use the globally available requirefunction

Take a look at a simple example:

To call other functions such as mul and div, use object destructuring as an alternative when requiring the module, for example, const { add } = require(‘./math’);. The code files for the section The Module System are placed at Code/Lesson-1/b-module-system.

Module Categories

You can place Node.js modules into three categories:

  • Built-in (native) modules: These are modules that come with Node.js itself; you don’t have to install them separately.
  • Third-party modules: These are modules that are often installed from a package repository. npm is a commonly used package repository, but you can still host packages on GitHub, your own private server, and so on.
  • Local modules: These are modules that you have created within your application, like the example given previously.

Built-In Modules

These are modules that can be used straight away without any further installation. All you need to do is to require them. There are quite a lot of them, but here are a few that you are likely to come across when building web applications:

  • assert: Provides a set of assertion tests to be used during unit testing
  • buffer: To handle binary data
  • child_process: To run a child process
  • crypto: To handle OpenSSL cryptographic functions
  • dns: To do DNS lookups and name resolution functions
  • events: To handle events
  • fs: To handle the filesystem
  • httpor https: For creating HTTP(s) servers
  • stream: To handle streaming data
  • util: To access utility functions like deprecate (for marking functions as deprecated), format (for string formatting), inspect (for object debugging), and so on

For example, the following code reads the content of the lesson-1/temp/sample.txt file using the in-built fs module:

npm ‚Äď Third-Party Module Registry

Node Package Manager (npm) is the package manager for JavaScript and the world’s largest software registry, enabling developers to discover packages of reusable code. To install an npm package, you only need to run the npm install <package-name> command within your project directory.

Here‚Äôs a simple example. If you want to use a package (library) like request in your project, you can run the following command on your Terminal, within your project directory:

To use it in your code, you should require it, like any other module:

More details about npm can be found at https://docs.npmjs.com/. When you run the npm install <module-name> command on your project for the first time, the node_modules folder gets created at the root of your project.

Scanning for node_modules

It’s worth noting how Node.js goes about resolving a particular required module. For example, if a /home/tony/projects/foo.js file has a require call require(‘bar’), Node.js scans the filesystem for node_modules in the following order. The first bar.js that is found is returned as follows:

  • /home/tony/projects/node_modules/bar.js
  • /home/tony/node_modules/bar.js
  • /home/node_module/bar.js
  • /node_modules/bar.js

Node.js looks for node_moduels/bar in the current folder followed by every parent folder until it reaches the root of the filesystem tree for the current file. Note that the module foo/index.js can be required as foo, without specifying an index and will be picked by default.

Handy npm Commands

Now dive a little deeper into npm, by looking at some of the handy npm commands that you will often need:

  • npm init: Initializes a Node.js project. This should be run at the root of your project and will create a respective jsonfile. This file usually has the following parts (keys):
  • name: Name of the project.
  • version: Version of the project.
  • description: Project description.
  • main: The entry-point to your project, the main file.
  • scripts: This will be a list of other keys whose values will be the scripts to be run, for example, test, dev-server. Therefore, to run this script, you will only need to type commands such as npm run dev-server, npm run test, and so on.
  • dependencies: List of third-party packages and their versions used by the project. Whenever you do npm install <package-name> –save, this list is automatically updated.
  • devDependencies: List of third-party packages that are not required for production, but only during development. This will usually include packages that help to automate your development workflow, for example, task runners like gulp.js. This list is automatically updated whenever you do npm install <package-name> –save-dev.
  • npm install: This will install all the packages, as specified in the jsonfile.
  • npm install <package-name> <options>:
  • The –saveoption installs the package and saves the details in the json file.
  • The –save-devoption installs the package and saves the details in the json, under devDependencies.
  • The –globaloption installs the package globally in the whole system, not only in the current system. Due to permissions, this might require running the command with administrator rights, for example, sudo npm install <package-name> –global.
  • npm install <package-name>@<version>, installs a specific version of a package. Usually, if a version is not specified, the latest version will be installed.
  • npm list: Lists the packages that have been installed for the project, reading from what is installed in node_modules.
  • npm uninstall <package-name>: Removes an installed package.
  • npm outdated: Lists installed packages that are outdated, that is, newer versions have been released.

Local Modules

You have already looked at how local modules are loaded from the previous example that had math.js and index.js.

Since JavaScript Object Notation (JSON) is such an important part of the web, Node.js has fully embraced it as a data format, even locally. You can load a JSON object from the local filesystem the same way you load a JavaScript module. During the module loading sequence, whenever a file.js is not found, Node.js looks for a file.json.

See the example files in lesson-1/b-module-system/1-basics/load-json.js:

Here, you will notice that once required, the JSON file is transformed into a JavaScript object implicitly. Other languages will have you read the file and perhaps use a different mechanism to convert the content into a data structure such as a map, a dictionary, and so on.

For local files, the extension is optional, but should there be a conflict, it might be necessary to specify the extension. If you have both a sample.js and a sample.json file in the same folder, the .js file will be picked by default; it would be prudent to specify the extension, for example const config = require(‘./config/sample.json’).

When you run npm install, without specifying the module to install, npm will install the list of packages specified (under dependencies and devDependencies in the package.json file in your project). If package.json does not exist, it will give an error indicating that no such file has been found.

Activity: Running Basic Node.js Code

Open the IDE and the Terminal to implement this solution and learn how to write a basic Node.js file and run it. Write a very basic mathematical library with handy mathematical functions using the following steps:

  1. Create your project directory (folder), where all the code for this will be kept. Inside this directory, create another directory named lesson-1, and inside it, create another directory called activity-a. All this can be done using the following command:

  1. Inside activity-a, create a file using the touch maths.js
  2. Inside this file, create the following functions:
  • add: This takes any two numbers and returns the sum of both, for example, add(2, 5)returns 7
  • sum: Unlike add, sum takes any number of numbers and returns their sum, for example, sum(10, 5, 6)returns 21
  1. After these functions, write the following code to act as tests for your code:

  1. Now, on the Terminal, change directory to lesson-1.
  2. To run the code, run the following command:

The 16 and 21 values should be printed out on the Terminal.

Activity: Using a Third-Party Package

This activity will build upon the, Running Basic Node.js activity. If the argument is a single array, sum up the numbers, and if it’s more than one array, first combine the arrays into one before summing up. Use the concat() function from lodash, which is a third-party package that you need to install.

Now create a new function, sumArray, which can sum up numbers from one or more arrays using the following steps:

  1. Inside Lesson-1, create another folder called activity-b.
  2. On the Terminal, change directory to activity-band run the following command:

  1. This will take you to an interactive prompt; just press Enter all the way, leaving the answers as suggested defaults. The aim here is to get a json file, which will help organize your installed packages.
  2. Since you‚Äôll be using lodash, install it. Run the following command:

Notice that you‚Äôre adding the –save option on your command so that the package installed can be tracked in package.json. When you open the package.json file created in step 3, you will see an added dependencies key with the details.

  1. Create a jsfile in the activity-b directory and copy the math.js code from ActivityRunning Basic Node.js into this file.
  2. Now, add the sumArrayfunction right after the sum
  3. Start with requiring lodash, which you installed in step 4 since you‚Äôre going to use it in the sumArrayfunction:

  1. The sumArrayfunction should call the sum function to reuse your code. Use the spread operator on the array. See the following code:

  1. At the end of the file, export the three functions, add, sum, and sumArraywith exports.
  2. In the same activity-bfolder, create a file, js.
  3. In jsfile, require ./math.js and go ahead to use sumArray:

  1. Run the following code on the Terminal:

You should see 21 and 30 printed out.

If you found this article interesting, you can explore Anthony Nandaa’s Beginning API Development with Node.js to learn everything you need to get up and running with cutting-edge API development using JavaScript and Node.js. Beginning API Development with Node.js begins with the basics of Node.js in the context of backend development and quickly leads you through the creation of an example client that pairs up with a fully authenticated API implementation.

How to Work with the Latest JS features in React

Working with the latest javascript features in React

React is mainly written with modern JavaScript (ES6, ES7, and ES8). If you want to take advantage of React, there are some modern JS features that you should master to get the best results for your React applications.

In this article, you’ll learn the essential JS features so that you are ready to start working on your first React application.

How to do it

In this section, you’ll see how to use the most important JS features in React:

  • let and¬†const: The new way to declare variables in JavaScript is using¬†let¬†or¬†const. You can use¬†let¬†to declare variables that can change their value but in a block scope. The difference between¬†let¬†and¬†var is that¬†let¬†is a block scoped variable that cannot be global, and with¬†var, you can declare a global variable, for example:

  • The best way to understand block scope is by declaring a¬†forloop¬†with¬†var¬†and¬†let. First, use¬†var¬†and see its behavior:

  • If you write the same code with¬†let, this will be the result:

  • With¬†const, you can declare constants, which means that the value can’t be changed (except for arrays and objects):

  • If you declare an array with¬†const, you can manipulate the array elements (add, remove, or modify elements):

  • Also, using objects, you can add, remove, or modify the nodes:

  • Spread operator:The spread operator (…) splits an iterable object into individual¬†values. In React, it can be used to push values into another array, for example when you want to add a new item to a to-do list utilizing¬†setState:

  • Also, the Spread operator can be used in React to spread attributes (props) in JSX:

  • Rest parameter:The¬†rest¬†parameter is also represented by¬†…. The last parameter in¬†a function prefixed with¬†…¬†is called the rest parameter. The¬†rest¬†parameter is an array that will contain the rest of the parameters of a function when the number of arguments exceeds the number of named parameters:

  • Destructuring:¬†The destructuring assignment javascript feature is the most used feature in React. It is an expression that allows you to assign the values or properties of an iterable object to variables. Generally, with this, you can convert your component props into variables (or constants):¬† ¬†

  • Arrow functions: In Javascript ES6 provides a new way to create functions using the¬†=> These functions are called arrow functions. This new¬†method¬†has a shorter syntax, and the arrow functions are anonymous functions. In React, arrow functions are used as a way to bind the¬†this object in your methods instead of binding it in the constructor:

  • Template literals:¬†The template literal is a new way to create a string using backticks ( ) instead of single quotes (‘ ‘)¬† ¬†or double quotes (” “). React uses template literals to concatenate class names or render a string using a ternary operator:
  • Map: The¬†map()method returns a new array with the results¬†of calling a provided function on each element in the calling array. Map use is widespread in React and mainly used to render multiple elements inside a React component.For example, it can be used to render a list of tasks:

  • assign(): The¬†Object.assign()method is used to copy the values of all¬†enumerable own properties from one or more source objects to a target object. It will return the target object. This method is used mainly with Redux to create immutable objects and return a new state to the reducers:

  • Classes: JavaScript classes, introduced in ES6, are mainly a new syntax for the¬†existing¬†prototype-based inheritance. Classes are functions and are not hoisted. React uses classes to create class¬†Components:

  • Static methods: Static methods are not called on instances of the class. Instead, they’re called on the class itself. These are often utility functions, such as functions to create or clone objects. In React, they can be used to define the¬†PropTypes in a component:

  • Promises:The¬†Promise¬†object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Use promises in React to handle requests using axios or fetch; also, you can use Promises to implement server-side rendering.
  • async/await:¬†The async function declaration defines an asynchronous function, which returns an¬†AsyncFunction This can also be used to perform a server request, for example, using axios:

If you found this article interesting, you can explore React Cookbook, which covers UI development, animations, component architecture, routing, databases, testing, and debugging with React. React Cookbook will save you from a lot of trial and error and developmental headaches, and you’ll be on the road to becoming a React expert.

Creating Queues for In-Order Executions With JavaScript by using WeakMap()

A queue is a programming construct that bears a heavy resemblance to real-world queues, for example, a queue at the movie theater, ATMs, or the bank. Queues, as opposed to stacks, are first-in-first-out (FIFO), so whatever goes in first comes out first as well. This is especially helpful when you would like to maintain data in the same sequence in which it flows.

Types of queues

Before you understand queues, take a quick look at the types of queues that you may want to use in your applications:

  • Simple queue: In a simple FIFO queue, the¬†order¬†is retained and¬†the data¬†leaves in the same order in which it comes in
  • Priority queue:¬†A¬†queue¬†in which the elements are given a predefined priority
  • Circular queue:¬†Similar to a simple queue, except that the back of the¬†queue¬†is followed by the front of the queue
  • Double ended queue(Dequeue): Similar to the simple¬†queue¬†but can add or remove elements from either the front or the back of the queue

Implementing APIs

Implementing an API is never as easy as it seems. When making generic classes, you can never predict what kind of situation your queue is going to be used in. Some of the most common operations that you can add to the queue are as follows:

  • add(): Pushes an¬†item¬†to the back of the queue
  • remove(): Removes an¬†item¬†from the start of the queue
  • peek(): Shows the last¬†item¬†added¬†to¬†the queue
  • front(): Returns the¬†item¬†at the front of the queue
  • clear(): Empties¬†the¬†queue
  • size(): Gets¬†the¬†current size of the queue

Creating a queue

Of the four types of queues discussed earlier, this article will teach you to implement a simple and priority queue.

A simple queue

To create a queue, use the following steps:

  1. Define a constructor():

  1. Use WeakMap()for in-memory data storage:

  1. Implement the methods described previously in the API:

You need to wrap the entire class inside an IIFE because you don’t want to make Queue¬†items accessible from the outside:

Testing a simple queue

To test this queue, you can simply instantiate it and add/remove some items to/from the queue:

As you can see in above code, all the elements are treated the same. Irrespective of the data they contain, elements are always treated in a FIFO fashion. Although that is a good approach, sometimes you may need something more: the ability to prioritize elements that are coming in and leaving the queue.

Priority Queue

A priority queue is operationally similar to a simple queue, that is, they support the same API, but there is a small addition to the data they hold. Along with the element (your data), they can also persist a priority, which is just a numerical value indicating the priority of your element in the queue.

Addition or removal of these elements from the queue is based on priority. You can either have a minimum priority queue¬†or a maximum priority queue, to help establish whether you are adding elements based on increasing priority or decreasing priority. Now let’s see how we can use the add() method in the simple queue:

Since you are accounting for the priority of the elements while they are being inserted into the stack, you do not have to concern yourself with priority while you remove elements from the queue. So, the remove() method is the same for both simple and priority queues. Other utility methods, such as front(), clear(), peek(), and size(), have no correlation with the type of data that is being saved in the queue, so they remain unchanged as well.

A smart move while creating a priority queue would be to optimize your code and decide whether you would like to determine the priority at the time of addition or removal. That way, you are not over calculating or analyzing your dataset at each step.

Testing a priority queue

First set up the data for testing the queue:

Visually, the preceding steps would generate a queue that looks as follows:

Note how when you add an element with a priority 2 it gets placed ahead of all the elements with priority 1:

And when you add an element with priority 1 (lowest), it gets added to the end of the queue:

In the above image, by adding the last element apply the lowest priority in the order, which makes it the last element of the queue, thus keeping all the elements ordered based on priority.

Now, remove the elements from the queue:

There you have it: the creation of simple and priority queue in JavaScript using WeakMap().

If you found this article interesting, you can explore Kashyap Mukkamala’s Hands-On Data Structures and Algorithms with JavaScript to increase your productivity by implementing complex data structures and algorithms. This book will help you gain the skills and expertise necessary to create and employ various data structures in a way that is demanded by your project or use case.