I recently wrote a tutorial titled, Creating a User Profile Store with Node.js and a NoSQL Database, as it is a very popular subject and use-case when it comes to NoSQL databases. In that tutorial we created an API using Node.js and Couchbase for storing users, information associated to particular users, and expiring sessions. However, it was strictly backend related with no user interface.

What if we wanted to realistically use the user profile store API? We’re going to see how to create a client front-end written in Angular with TypeScript, that communicates with each of the API endpoints.

Before continuing, we are assuming that you’ve followed the previous tutorial and were successful. We’re also going to assume that you have the Angular CLI installed and ready to go.

Create an Angular Project with the Necessary Components

The client front-end will be completely fresh, as in we’re going to create it from nothing. From a design perspective it isn’t going to look great because I have no class. Get it? That’s a CSS joke. In all seriousness, application attractiveness is not our goal, but instead functionality.

From the Angular CLI, execute the following command:

The above command will create a new project in the CLI path. With the project created, we’ll need to create a component for each of our expected application pages.

Execute the following with the Angular CLI:

Four components will be created, each with appropriate TypeScript and HTML files. Before we start adding logic to them, we need to tie them together for navigation purposes.

Open the project’s src/app/app.module.ts file and include the following:

Most of the above was created by the Angular CLI, however, we added a few module imports and imported them along with the routes into the @NgModule block.

To activate our navigation, we’ll need to update a file. Open the project’s src/app/app.component.html file and replace all the content with the following:

At this point the project has a basic configuration.

Let’s have a look at handling the creation of user profiles and signing in with the account information.

Handling Login and Registration

The first screen the user will see is the login screen. The purpose here is to collect a username and password, send it to the API, get a session id as a response, and use it in every future page of the application.

Open the project’s src/app/login/login.component.ts file and include the following TypeScript code:

There are some important things happening in the above code so we’re going to break it down.

Our intention is to bind an object to a form in the HTML markup. This object will be the input variable. In the constructor method we set each possible property as an empty value which will be reflected in the UI.

When the user decides to sign in, the appropriate header information is set for the request and the object is sent to the server. If successful, the response will be an object with the session id. We’re going to pass it to the next page as a query parameter.

The HTML markup that pairs with this TypeScript is found in the project’s src/app/login/login.component.html and it looks like the following:

I told you the UI was going to be basic didn’t I?

What is important here is the use of the [(ngModel)] attributes that are used for data binding. We also offer navigation to the registration page through the [routerLink] attribute.

So what does the registration component look like?

Open the project’s src/app/register/register.component.ts file and include the following TypeScript code:

You’ll notice from the above snippet that pretty much all the registration code is the same as the login code. That is because we’re just collecting form data and sending it to a different API endpoint.

The corresponding HTML found in the project’s src/app/register/register.component.html file looks like this:

The HTML contains form elements bound with the [(ngModel)] attribute as well as a link back to the login page.

Remember, after we’ve signed in we are passing the session to the user specific pages. This will allow us to get user specific information from our profile store.

Creating and Viewing Blog Articles for a Particular User in the Profile Store

After signing in, the user is taken to a page where they can view a list of blog articles that they’ve written. Remember, our backend is connecting NoSQL documents through a profile id that we’re defining.

To view blog articles, the session id passed from the previous page needs to be set as a header in a request. The result from the request can be immediately rendered to the screen.

Open the project’s src/app/blogs/blogs.component.ts file and include the following TypeScript code:

This file follows a similar strategy to how we handled login and registration.

In terms of variables, we create a private variable called sid which will hold the session passed from the previous page. The entries variable will be an array of blog entries for an individual returned from the API endpoint.

When the page loads we should be displaying the blog entries. It is never a good idea to load or request data from within the constructor method, so instead we use the ngOnInit method.

In the ngOnInit method we can grab the passed parameters and construct an authorization header. Then we make a request against our endpoint that contains the header.

To create a new blog entry, we can pass the sid to the next route:

This is just like what we saw with the login screen.

The HTML markup that powers the UI will be no more complex than the TypeScript logic that powers it. The HTML can be seen in the src/app/blogs/blogs.component.html like so:

Creating a blog entry will have similar logic to what we’ve seen already. Open the project’s src/app/blog/blog.component.ts file and include the following TypeScript code:

In the above code we are initializing our form data and retrieving the sid that was passed from the previous page.

When we try to save the entry, we construct an appropriate header that contains the session id and then send it to the API with the form data. Once complete, we can navigate backwards in the stack.

The HTML for the UI of this page is in the src/app/blog/blog.component.html file like so:

The same rules as the other pages were applied.

Improving the Node.js Backend to the Profile Store

You may notice a few weird things happening when you try the backend and front-end together. For example, cross-origin resource sharing (CORS) errors might be thrown, or your data might not be immediately available after creation.

We’re going to fix those minor issues.

The first step is to fix any CORS issues that might come up from running our applications on different ports. Within your Node.js project, execute the following command:

This will download a package that we can use in our project.

Within your project’s app.js file, import the package and use it like the following:

This will allow requests from anywhere. You should use care when doing this in production, but for our testing purposes, it solves our problem.

The next issue you might face is in the realm of query consistency in Couchbase. By default, Couchbase will try to be fast, which means it may return data faster than the indexes update. When this happens you might have freshly created data missing from your results.

I explained how to correct this in a previous tutorial, but a quick recap is below.

In our blogs endpoint, we can define the scan consistency, and in this case we are telling it to wait until the index has updated before returning the data. This is a fast operation, so don’t think that it will crawl when you do this. It just won’t be as fast as the default.

At this point the front-end should work flawlessly with the backend!

Conclusion

You just saw how to create a simple client front-end using Angular and TypeScript for the user profile store we saw in a previous example. This client front-end is one of many possible examples for a front-end because this is a modular full stack application. This means that the backend can be in any language and the front-end can be in any language.

In a production scenario, you might consider creating an Angular service for handling the session id, so that way it doesn’t need to be passed around with each navigation event.

Posted by Nic Raboy, Developer Advocate, Couchbase

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

Leave a reply