Creating a Blogging App Using Angular & MongoDB: Edit Post

In the previous part of this tutorial series you learnt how to create the add post component to add new blog posts. You learnt how to create the REST API endpoint to add a new post to the MongoDB database.

In this part of the tutorial series, you’ll learn how to implement the functionality to edit an existing blog post from the blog post list.

Getting Started

Let’s get started by cloning the source code from the last part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the client and server application.

Point your browser to http://localhost:4200 and you will have the application running.

Adding the Edit Post View

In the ShowPostComponent, you’ll add two icons for editing and deleting the blog post. You’ll make use of Font Awesome to display the edit and delete icons.

Download and include the font awesome folder in the assets folder.

Font Awesome In Assets Folder

In the src/app/index.html page, include a reference to the font awesome CSS style.

Now modify the show-post/show-post.component.html file to include the HTML for the edit and delete icons.

Here is how the show-post.component.html file looks:

Save the above changes and restart the client application. Log into the application and you will be able to view the edit and delete icons corresponding to each listed blog post.

Angular Blog App - Edit And Delete Icon

Populating the Edit Detail in a Popup

When the user clicks the edit icon corresponding to any blog post, you need to populate the blog post details in the add post popup for updating.

Add a click method to the edit icon.

Inside the CommonService, you need to define an observable to keep track of when the edit button is clicked. Define the observable as shown:

Define another variable to keep track of the post to be edited.

Whenever the edit button is clicked, you’ll keep the post to be edited in the CommonService and trigger the observable to notify of post edit. Define two methods to set the post to be edited and to notify post edit.

Inside the click method, you’ll call the setPostToEdit method from CommonService. Here is how the editPost method looks:

You will have the post detail in the common service when the user clicks the edit button. To show the add post popup for updating, you need to click the add post button programmatically.

Inside the home/home.component.html file, add a # identifier to the add post button.

Import ViewChild and ElementRef inside the home.component.ts file.

Define a reference to the add button inside the home.component.ts file.

Inside the HomeComponent constructor, subscribe to the postEdit_Observable from CommonService. On calling the postEdit_Observable subscription callback, invoke the add button click to show the popup. Here is how the home.component.ts file looks:

You need to subscribe to postEdit_Observable in the add-post.component.ts file to set the post to be edited on the post variable. Here is how the ngOnInit method in add-post.component.ts looks:

Save the above changes and restart the client server. Log into the application and click on the edit button against any blog post. You will be able to view the post details populated in the add post popup.

Angular Blog App - Update Post

Creating the Update Post REST API

Inside server/app.js, let’s define another REST API endpoint to update post details based on the ID of the post. Here is how it looks:

Let’s first use Mongoose to connect to the MongoDB database.

Once the connection is established, you make use of the update method on the Post model.

You’ll be updating the post based on the ID of the post passed. As seen in the above code, you have specified the post _id to be updated. In the second option, you have specified the fields to be updated, which are title and description.

Once the details get updated, you’ll return the status along with the number of rows affected during the update. Here is how the REST API endpoint for the post update looks:

Making the REST API Call to Update

The ID returned for each post from the MongoDB is _id, so you need to modify the id of our model src/app/models/post.model.ts. Here is how it looks:

When you click the add post button, the method called will be addPost. Inside the addPost method in add-post.component.ts, you’ll check if the post object has an _id. If an _id is present then you need to call the update method from the service, else you’ll call the add post service method.

Create a method called updatePost inside the add-post.service.ts file.

Here is how the modified addPost method from the add-post.component.ts file looks:

Save the above changes and restart both Angular and Node server. Log into the application and try editing a post. You will have a popup displayed to edit the details on clicking the edit button. Click the add button and the details will be updated and displayed in the blog post list.

Wrapping It Up

In this tutorial, you implemented the functionality to update the existing blog post details. You created the back-end REST API endpoint to update the blog post details based on the blog post ID. You made use of the Mongoose client to update the details of the blog post in the MongoDB database.

In the next part, you’ll implement the delete post and log out functionality.

How was your experience so far? Do let us know your thoughts, suggestions, or any corrections in the comments below.

Source code from this tutorial is available on GitHub


Source: Nettuts Web Development

Creating a Blogging App Using Angular & MongoDB: Add Post

In the previous part of the Angular blog tutorial series, you learnt how to create the ShowPostComponent to display the list of blog posts on the home page. You fetched the records that were inserted from the MongoDB shell using the created REST API endpoint.

In this tutorial, you’ll be creating a new component called AddPostComponent to provide the user interface to add a new blog post to the MongoDB database.

Getting Started

Let’s get started by cloning the source code from the previous part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the client and server application.

Point your browser to http://localhost:4200 and you should have the application running.

Creating the Add Post Component

Let’s get started by creating the AddPostComponent. Create a folder called add-post inside the src/app folder. Inside the add-post folder, create a file called add-post.component.ts and add the following code:

Create a file called add-post.component.html and the following HTML code:

You’ll be showing the add post component as a popup.

Now you need to add the AddPostComponent to the NgModule. Import the AddPostComponent in the app.module.ts file.

Add the component to the NgModule declarations list. Here is how it looks:

To trigger the add post popup, you have already added the data-target attribute to the button in home.component.html.

Save the above changes and restart the application. Log into the application and click on the Add link in the home page. You will have the AddPostComponent displayed as a popup.

Angular Blog Application - Add Post Popup

Implementing the Add Post Functionality

Add the ngModel directive to the input elements for title and description.

Add a click directive to the button for calling the method to save the blog post.

Import the Post model from src/app/models/post.model.ts in the add-post.component.ts file.

Define the post variable in the add-post.component.ts file.

Define the addPost method inside the add-post.component.ts file. From the addPost method, you’ll validate the entered title and description and make a call to the service method to call the REST API. Here is how the method looks:

Let’s create the service file for the component AddPostComponent. Create a file called add-post.service.ts and add the following code:

Inside the AddPostService, create a method called addPost to make the REST API call.

As seen in the above code, you have made use of the HttpClient to make the API call and return the Observable.

In the add-post.component.ts file inside the addPost method, you’ll subscribe to the addPost method from the add-post.service.ts file.

Here is how the add-post.component.ts file looks:

Creating the REST API for Add Post

Let’s create a REST API end point for adding the blog post to the MongoDB database. In the server/app.js file, create an API end point as shown:

First, you need to connect to the MongoDB database using the Mongoose client.

Once the connection has been established, you need to create a model object using the Post schema defined in the server/model/post.js file. 

As seen in the above code, you created the Post object using the title and description passed in from the request req object.

Call the save method on the Post object to save the entry to MongoDB.

As seen in the above code, once the save method callback is called with no error, it will return the success message along with the returned object doc.

Here is how the REST API end point finally looks:

Save the above changes and restart both Angular and Node servers. Sign in to the application and try to add a new blog post. Once you click on the Add button, check the browser console and you will have the success response logged.

When the blog post details are added to the database successfully, you need to close the popup. In order to close the popup, there is a close button which you need to click programmatically.

You’ll be using the @ViewChild decorator to access the close button.

Import ViewChild and ElementRef in AddPostComponent.

Inside the AddPostComponent, define the following variable:

Initiate the closeBtn click using the following code:

Add the above code to the success callback of the addPost method. Here is the addPost method from add-post.component.ts.

Save the changes and restart the client server. Log into the application and try adding a new blog post. Once the blog post details have been saved successfully, the popup will close.

Refreshing the Blog List

One thing to note is that the newly added blog post doesn’t show up in the blog post list. So you need to add a trigger to notify when to update the ShowPostComponent. You’ll be making use of a common service to communicate between the two components.

Create a folder called service inside the src/app folder. Create a file called common.service.ts with the following code:

As seen in the above code, you have declared a Subject called postAdded_Observable to keep track of the new blog post addition to the database. Whenever a new blog post is added to the database, you’ll call the notifyPostAddition method, which will notify the subscribers about the update.

Import the CommonService in app.module.ts and include it in the NgModule provider’s list. Here is how it looks:

Import CommonService in the show-post.component.ts file and initialize it in the constructor method.

Inside the ngOnInit method, subscribe to the postAdded_Observable variable and load the getAllPost method. Here is how the ngOnInit method looks:

Import CommonService in the add-post.component.ts file and call the notifyPostAddition method once the blog post has been added. Here is how the addPost method from the AddPostComponent looks:

Save the above changes and restart the client server. Log in to the application and add a new blog post. Once added, the blog post list gets updated with the new blog post.

Wrapping It Up

In this tutorial, you created the AddPostComponent to add the blog post details to the MongoDB database. You created the REST API for saving a blog post to the MongoDB database using the Mongoose client.

In the next part of the series, you’ll implement the functionality to edit and update the blog post details.

Source code for this tutorial is available on GitHub.

How was your experience so far? Do let me know your valuable suggestions in the comments below.


Source: Nettuts Web Development

Introduction to Mocking in Python

Mocking is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. This tutorial will discuss in detail what mocking is and how to use it in Python applications.

What Is Mocking?

Mocking is a library for testing in Python which allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.

In Python, mocking is accomplished by replacing parts of your system with mock objects using the unittest.mock module. This module contains a number of useful classes and functions, namely the patch function (as decorator and context manager) and the MagicMock class. These two components are very important in achieving mocking in Python.

A mock function call usually returns a predefined value immediately.  A mock object’s attributes and methods are defined in the test as well, without creating the real object.

Mocking also allows you to return predefined values to each function call when writing tests. This allows you to have more control when testing.

Prerequisites

Mock is available in Python 3, but if you are using a Python version below
3.3, you can still use unittest.mock by importing it as a separate library like so.

Benefits of Mocking

Some of the benefits of mocking include:

  1. Avoiding overdependence. Mocking reduces the dependence of functions. For instance, if you have a function A class that depends on a function B, you will need to write a few unit tests covering the features provided by function B. Let’s say the code grows in future and you have more functions, i.e. A depends on B, B depends on C, and C depends on D. If a fault is introduced in Z, all your unit tests will fail.
  2. Reduced overload. This applies to resource-intensive functions. A mock of that function would cut down on unnecessary resource usage during testing, therefore reducing test run time.
  3. Bypass time constraints in functions. This applies to scheduled activities. Imagine a process that has been scheduled to execute every hour. In such a situation, mocking the time source lets you actually unit test such logic so that your test doesn’t have to run for hours, waiting for the time to pass.

Usage

Usage of mock is simple as:

Here, we import the mock module, create a mock object, and specify return values. When the mock object is called, we want it to be able to return some values. In our case, we want the mock object to return a value of 10. If we call the mock object with the arguments (1, 4, foo ='bar'), the result will be the value 10, which was defined as a return value.

You can also raise exceptions inside mocks as follows:

The side_effects argument allows you to perform certain things like raising an exception when a mock is called.

Example

Consider this simple function:

This function performs an API request to the Google webpage and returns a response.

The corresponding simple test case will be as follows:

Running the above test should give an output like so:

Let’s introduce mocking to this example, and the resulting test with the Mock module will be as shown below:

Running the above test should give an output like so:

As seen above, the mocking module takes less time to make the same API call as the normal test case.

Larger Example

Let’s assume you have a script that interacts with an external API and makes calls to that API whenever a certain function is called. In this example, we are going to use the Twitter API to implement a Python script which will post to the Twitter profile page.

We don’t want to post messages on Twitter every time we test the script, and that’s where Mocking comes in.

Let’s get started. We will be using the python-twitter library, and the first thing we will do is create a folder python_mock and, inside the folder, create two files, namely tweet.py and mock_test.py.

Write the following code to the file tweet.py.

In the code above, we first import the Twitter library and then define the authentication credentials, which you can easily get from the Twitter Apps page.

The Twitter API is exposed via the twitter.Api class, so we create the class by passing our tokens and secret keys.

The post_tweet function takes in an authentication object and the message and then posts the tweet to the Twitter profile.

We then go ahead and mock the API call to Twitter so that the API doesn’t post to Twitter every time it is called. Go ahead and open the mock_test.py file and add the following code.

Running the above test should give an output like so:

Conclusion

This tutorial has covered most of the fundamentals of mocking and how to use mocking to perform external API calls. For more information, visit the official Python mocking documentation. You can also find additional resources on authentication with the Twitter API in this tutorial.

Additionally, don’t hesitate to see what we have available for sale and for study in the Envato Market, and please go ahead and ask any questions and provide your valuable feedback using the feed below.


Source: Nettuts Web Development

Creating a Blogging App Using Angular & MongoDB: Show Post

In the last part of the tutorial series, you saw how to write the REST API endpoint for user login. You used Mongoose to interact with MongoDB from Node. After successful validation, you saw how to use Angular Router for navigating to the HomeComponent.

In this part of the tutorial series, you’ll create a component to list the blog post details on the home page.

Getting Started

Let’s get started by cloning the source code from the last part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the client and server application.

Point your browser to http://localhost:4200 and you should have the application running.

Angular Blogging App

Creating the Show Post Component

Once the user gets logged into the application, you’ll display the HomeComponent. HomeComponent acts like a wrapper component for all the components displayed inside it. You’ll be displaying the list of blog posts added by the user in the HomeComponent.

To display the blog posts, let’s create a new component called ShowPostComponent. Create a folder called show-post inside the src/app folder. Inside the show-post folder, create a file called show-post.component.html and add the following HTML code:

Create a file called show-post.component.ts which will contain the ShowPostComponent class. Here is how it looks:

Import the ShowPostComponent in the app.module.ts file.

Add ShowPostComponent in the NgModule in the app.module.ts file. 

Modify the home.component.html file to include the ShowPostComponent selector.

Here is how the modified home.component.html file looks:

Save the above changes and refresh the client application. On signing into the application, you will be able to view the blog posts listed.

Angular Blog App - Show Post Component

Creating the Show Post Component Service

The data displayed in the ShowPostComponent service displays hard-coded data. You’ll need a service to query the blog post list from the MongoDB database. Let’s create a service for your ShowPostComponent.

Create a file called show-post.service.ts in src/app/show-post and add the following code:

Inside the ShowPostService, create a method called getAllPost, which will make the REST API call to get the blog post list. Here is how it looks:

Here is how the show-post.service.ts file looks:

Next, you need to write down the REST API to query the MongoDB collection to get the list of blog posts.

On the server side, let’s get started by creating the model for the post. Inside the models folder, create a file called post.js. Require the Mongoose module and create a schema for the blog post and export it. Here is how the /server/models/post.js looks:

Export the above defined post.js file in app.js.

Create an API endpoint /api/post/getAllPost for fetching the list of blog posts. Use the mongoose client to connect to the MongoDB database.

Once you have the connection established, you can use the Post model to find the list of blog posts.

The .find callback returns the list of documents.

The documents returned will be in ascending order, so add a condition to sort the blog posts in descending order.

Once you have the list of documents queried from the database, return the data along with the status. Here is how the REST API looks:

Making the API Call

In the show-post.component.ts file, define an array list for keeping the results of the API call.

Import the ShowPostService in the ShowPostComponent.

Add the ShowPostService as a provider to the ShowPostComponent.

Define a method called getAllPost to make a call to the service method. Here is how it looks:

As seen in the above code, the result data is set to the posts variable.

Make a call to the above defined method from the ngOnInit method, so that the blog post details are fetched as soon as the component is initialized.

Here is how the show-post.component.ts file looks:

Rendering the Blog Posts

The MongoDB collection might not have entries to be queried. So let’s add a few entries in the MongoDB from the mongo shell.

Enter the MongoDB shell by typing in the following command:

Once you enter the mongo shell, check the database available in the MongoDB database.

Select the blogDb database from the listed entries.

Create a collection named post.

Insert a couple of entries into the post collection.

Now let’s bind our posts variable in the ShowPostComponent to the HTML code.

You’ll be making use of the ngFor directive to iterate over the posts variable and display the blog posts. Modify the show-post.component.html file as shown:

Save the above changes and restart the client and REST API server. Sign in to the application and you will have the inserted records from MongoDB displayed on the home page.

Angular Blog App - Dynamic Blog Post Listing

Wrapping It Up

In this tutorial, you created the ShowPostComponent to display the blog post details from the MongoDB database. You created the REST API for querying the MongoDB database using the Mongoose client from the Node server.

In the next part of the tutorial series, you’ll learn how to create the AddPostComponent for adding new posts from the application user interface.

Source code for this tutorial is available on GitHub.

How was your experience so far? Do let me know your valuable suggestions in the comments below.


Source: Nettuts Web Development

Creating a Blogging App Using Angular & MongoDB: Home

In the first part of the tutorial series, you saw how to get started with creating an Angular web app. You learnt how to set up the application and created the Login component.

In this part of the series, you’ll move further and write down the REST API required for interacting with the MongoDB bank end. You’ll also create the Home component which will be displayed after the user has logged in successfully.

Getting Started

Let’s get started by cloning the source code from the first part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the application server.

Point your browser to http://localhost:4200 and you should have the application running.

Creating the Login REST API

Inside the project folder AngularBlogApp-Home, create another folder called server. You’ll be writing the REST APIs using Node.js.

Navigate to the server folder and initialize the project.

Enter the required details and you should have the project initialized.

You’ll be using the Express framework for creating the server. Install Express using the following command:

Once you have Express installed, create a file called app.js. This will be the root file for your Node.js server.

Here is how the app.js file looks:

As seen in the above code, you imported express into app.js. Using express, you created an application app.

Using app, you exposed an endpoint /api/user/login which will display a message. Start the Node.js server using the following command:

Point your browser to http://localhost:3000/api/user/login and you should have the message displayed.

You’ll be making a POST request from the Angular service to the server with the username and password parameters. So you need to parse the request parameters.

Install body-parser, which is Node.js body-parsing middleware to parse request parameters.

Once you have it installed, import it in app.js .

Add the following code to the app.js file.

The above two body-parser options return the middleware that only parses json and urlencoded bodies and only looks at requests where the Content-Type header matches the type option.

You’ll be using Mongoose to interact with MongoDB from Node.js. So install Mongoose using Node Package Manager (npm).

Once you have mongoose installed, import it in app.js.

Define the MongoDB database URL in app.js.

Let’s use Mongoose to connect to the MongoDB database. Here is how it looks:

If the connection is established, the message gets logged along with the username and password.

Here is how the app.js file looks:

Restart the Node server using the following command:

To connect to the Node server from the Angular application, you need to set the proxy. Create a file called proxy.json inside the client/src folder. Here is how it looks:

Modify the client package.json file to start the application using the proxy file.

Save the changes and start the client server.

Point your browser to http://localhost:4200 and enter the username and password. Click the sign in button and you should have the parameters logged in the Node console.

Validating the User Login

To interact with MongoDB using Mongoose, you need to define a schema and create a model. Inside the server folder, create a folder called model.

Create a file called user.js inside the model folder. Add the following code to the user.js file:

As seen in the above code, you imported mongoose into user.js. You created a userSchema using the mongoose schema and created the User model using the mongoose model.

Import the user.js file inside the app.js file.

Before querying the MongoDB user collection, you need to create the collection. Go to the MongoDB shell by typing mongo. Create the collection user using the following command:

Insert a record which you’ll be querying against.

Now, once mongoose gets connected to MongoDB, you’ll find the record from the database using the username and password passed in. Here is how the API looks:

As seen in the above code, once you receive a response from the database, you return the same to the client side.

Save the above changes and try running the client and server. Enter the username as roy and password as 123 and you should be able to view the result in the browser console.

Redirecting to the Home Component

Once the user has been validated successfully, you need to redirect the user to the Home component. So let’s start by creating the Home component. 

Create a folder called Home inside the src/app folder. Create a file called home.component.html and add the following HTML code:

Create a file called home.component.css and add the following CSS style:

Create the component file called home.component.ts and add the following code:

As seen in the above code, you just created the HomeComponent using the @Component decorator and specifying the selector, templateUrl, and styleUrls

Add the HomeComponent to the NgModules in app.module.ts.

Import the HomeComponent in the app.routing.ts and define a route for home.

In the validateLogin method in the login.component.ts file, on successful validation redirect the user to the HomeComponent. To redirect, you need to import the Angular Router.

If the response from the API call is a success, you’ll navigate to the HomeComponent using the Angular Router.

Here is how the login.component.ts file looks:

Save the above changes and restart the server. Sign in to the application using the existing username and password, and you will be redirected to the HomeComponent.

Angular Blog App Home Component

Wrapping It Up

In this tutorial, you saw how to write the REST API endpoint for user sign-in. You learnt how to use Mongoose to interact with MongoDB from Node. After successful validation, you saw how to use Angular Router for navigating to the HomeComponent.

How was your experience learning to write an Angular application and its back end? Do let us know your thoughts and suggestions in the comments below.

Source code from this tutorial is available on GitHub.


Source: Nettuts Web Development

Phoenix I18n

In my previous articles I covered the various aspects of Elixir—a modern functional programming language. Today, however, I would like to step aside from the language itself and discuss a very fast and reliable MVC framework called Phoenix that is written in Elixir.

This framework emerged nearly five years ago and has received some traction since then. Of course, it is not as popular as Rails or Django yet, but it does have great potential and I really like it.

In this article we are going to see how to introduce I18n in Phoenix applications. What is I18n, you ask? Well, it is a numeronym that means “internationalization”, as there are exactly 18 characters between the first letter “i” and the last “n”. Probably, you have also met an L10n numeronym which means “localization”. Developers these days are so lazy they can’t even write a couple of extra characters, eh?

Internationalization is a very important process, especially if you foresee the application being used by people from all around the world. After all, not everyone knows English well, and having the app translated into a user’s native language gives a good impression.

It appears that the process of translating Phoenix applications is somewhat different from, say, translating Rails apps (but quite similar to the same process in Django). To translate Phoenix applications, we use quite a popular solution called Gettext, which has been around for more than 25 years already. Gettext works with special types of files, namely PO and POT, and supports features like scoping, pluralization, and other goodies. 

So in this post I am going to explain to you what Gettext is, how PO differs from POT, how to localize messages in Phoenix, and where to store translations. Also we are going to see how to switch the application’s locale and how to work with pluralization rules and domains.

Shall we start?

Internationalization With Gettext

Gettext is a battle-tested open-source internationalization tool initially introduced by Sun Microsystems in 1990. In 1995, GNU released its own version of Gettext, which is now considered to be the most popular out there (the latest version was 0.19.8 at the time of writing this article). Gettext may be used to create multilingual systems of any size and type, from web apps to operational systems. This solution is quite complex, and we are not going to discuss all its features, of course. The full Gettext documentation can be found at gnu.org.

Gettext provides you all the necessary tools to perform localization and presents some requirements on how translation files should be named and organized. Two file types are used to host translations: PO and MO.

PO (Portable Object) files store translations for given strings as well as pluralization rules and metadata. These files have quite a simple structure and can be easily edited by a human, so in this article we will stick to them. Each PO file contains translations (or part of the translations) for a single language and should be stored in a
directory named after this language: en, fr, de,
etc.

MO (Machine Object) files contain binary data not meant to be edited directly by a human. They are harder to work with, and discussing them is out of the scope of this article.

To make things more complex, there are also POT (Portable Object Template) files. They host only strings of data to translate, but not the translations themselves. Basically, POT files are used only as blueprints to create PO files for various locales.

Sample Phoenix Application

Okay, so now let’s proceed to practice! If you’d like to follow along, make sure you have installed the following:

Create a new sample application without a database by running:

--no-ecto says that the database should not be utilized by the app (Ecto is a tool to communicate with the DB itself). Note that the generator might require a couple of minutes to prepare everything.

Now use cd to go to the newly created i18ndemo folder and run the following command to boot the server:

Next, open the browser and navigate to http://localhost:4000, where you should see a “Welcome to Phoenix!” message.

Hello, Gettext!

What’s interesting about our Phoenix app and, specifically, the welcoming message is that Gettext is already being used by default. Go ahead and open the demo/lib/demo_web/templates/page/index.html.eex file which acts as a default starting page. Remove everything except for this code:

This welcoming message utilizes a gettext function which accepts a string to translate as the first argument. This string can be considered as a translation key, though it is somewhat different from the keys used in Rails I18n and some other frameworks. In Rails we would have used a key like page.welcome, whereas here the translated string is a key itself. So, if the translation cannot be found, we can display this string directly. Even a user who knows English poorly can get at least a basic sense of what’s going on.

This approach is quite handy actually—stop for a second and think about it. You have an application where all messages are in English. If you’d like to internationalize it, in the simplest case all you have to do is wrap your messages with the gettext function and provide translations for them (later we will see that the process of extracting the keys can be easily automated, which speeds things up even more).

Okay, let’s return to our small code snippet and take a look at the second argument passed to gettext: name: "Phoenix". This is a so-called binding—a parameter wrapped with %{} that we’d like to interpolate into the given translation. In this example, there is only one parameter called name.

We can also add one more message to this page for demonstration purposes: 

Adding a New Translation

Now that we have two messages on the root page, where should we add translations for them? It appears that all translations are stored under the priv/gettext folder, which has a predefined structure. Let’s take a moment to discuss how Gettext files should be organized (this applies not only to Phoenix but to any app using Gettext).

First of all, we should create a folder named after the locale it is going to store translations for. Inside, there should be a folder called LC_MESSAGES containing one or multiple .po files with the actual translations. In the simplest case, you’d have one default.po file per locale. default here is the domain’s (or scope’s) name. Domains are used to divide translations into various groups: for example, you might have domains named admin, wysiwig, cart, and other. This is convenient when you have a large application with hundreds of messages. For smaller apps, however, having a sole default domain is enough. 

So our file structure might look like this:

  • en
    • LC_MESSAGES
      • default.po
      • admin.po
  • ru
    • LC_MESSAGES
      • default.po
      • admin.po

To starting creating PO files, we first need the corresponding template (POT). We can create it manually, but I’m too lazy to do it this way. Let’s run the following command instead:

It is a very handy tool that scans the project’s files and checks whether Gettext is used anywhere. After the script finishes its job, a new priv/gettext/default.pot file containing strings to translate will be created.

As we’ve already learned, POT files are templates, so they store only the keys themselves, not the translations, so do not modify such files manually. Open a newly created file and take a look at its contents:

Convenient, isn’t it? All our messages were inserted automatically, and we can easily see exactly where they are located. msgid, as you’ve probably guessed, is the key, whereas msgstr is going to contain a translation.

The next step is, of course, generating a PO file. Run:

This script is going to utilize the default.pot template and create a default.po file in the priv/gettext/en/LC_MESSAGES folder.  For now, we have only an English locale, but support for another language will be added in the next section as well.

By the way, it is possible to create or update the POT template and all PO files in one go by using the following command:

Now let’s open the priv/gettext/en/LC_MESSAGES/default.po file, which has the following contents:

This is the file where we should perform the actual translation. Of course, it makes little sense to do so because the messages are already in English, so let’s proceed to the next section and add support for a second language.

Multiple Locales

Naturally, the default locale for Phoenix applications is English, but this setting can be changed easily by tweaking the config/config.exs file. For example, let’s set the default locale to Russian (feel free to stick with any other language of your choice):

It is also a good idea to specify the full list of all supported locales:

Now what we need to do is generate a new PO file containing translations for the Russian locale. It can be done by running the gettext.merge script again, but with a --locale switch:

Obviously, a priv/gettext/ru/LC_MESSAGES folder with the .po files inside will be generated. Note, by the way, that apart from the default.po file, we also have errors.po. This is a default place to translate error messages, but in this article we are going to ignore it.

Now tweak the priv/gettext/ru/LC_MESSAGES/default.po by adding some translations:

Now, depending on the chosen locale, Phoenix will render either English or Russian translations. But hold on! How can we actually switch between locales in our application? Let’s proceed to the next section and find out!

Switching Between Locales

Now that some translations are present, we need to enable our users to switch between locales. It appears that there is a third-party plug for that called set_locale. It works by extracting the chosen locale from the URL or Accept-Language HTTP header. So, to specify a locale in the URL, you would type http://localhost:4000/en/some_path. If the locale is not specified (or if an unsupported language was requested), one of two things will happen:

  • If the request contains an Accept-Language HTTP header and this locale is supported, the user will be redirected to a page with the corresponding locale.
  • Otherwise, the user will be automatically redirected to a URL that contains the code of the default locale.

Open the  mix.exs file and drop in set_locale to the deps function:

We must also add it to the application function:

Next, install everything:

Our router located at lib/demo_web/router.ex requires some changes as well. Specifically, we need to add a new plug to the :browser pipeline:

Also, create a new scope:

And that’s it! You can boot the server and navigate to http://localhost:4000/ru and http://localhost:4000/en. Note that the messages are translated properly, which is exactly what we need!

Alternatively, you may code a similar feature yourself by utilizing a Module plug. A small example can be found in the official Phoenix guide.

One last thing to mention is that in some cases you might need to enforce a specific locale. To do that, simply utilize a with_locale function:

Pluralization

We have learned the fundamentals of using Gettext with Phoenix, so the time has come to discuss slightly more complex things. Pluralization is one of them. Basically, working with plural and singular forms is a very common though potentially complex task. Things are more or less obvious in English as you have “1 apple”, “2 apples”, “9000 apples” etc (though “1 ox”, “2 oxen”!).

Unfortunately, in some other languages like Russian or Polish, the rules are more complex. For example, in the case of apples, you’d say “1 яблоко”, “2 яблока”, “9000 яблок”. But luckily for us, Phoenix has a Gettext.Plural behavior (you may see the behavior in action in one of my previous articles) that supports many different languages. Therefore all we have to do is take advantage of the ngettext function.

This function accepts three required arguments: a string in singular form, a string in plural form, and count. The fourth argument is optional and can contain bindings that should be interpolated into the translation.

Let’s see ngettext in action by saying how much money the user has by modifying the demo/lib/demo_web/templates/page/index.html.eex file:

%{count} is an interpolation that will be replaced with a number (540 in this case). Don’t forget to update the template and all PO files after adding the above string:

You will see that a new block was added to both default.po files:

We have not one but two keys here at once: in singular and in plural forms. msgstr[0] is going to contain some text to display when there is only one message. msgstr[1], of course, contains the text to show when there are multiple messages. This is okay for English, but not enough for Russian where we need to introduce a third case: 

Case 0 is used for 1 buck, and case 1 for zero or few bucks. Case 2 is used otherwise.

Scoping Translations With Domains

Another topic that I wanted to discuss in this article is devoted to domains. As we already know, domains are used to scope translations, mainly in large applications. Basically, they act like namespaces.

After all, you may end up in a situation when the same key is used in multiple places, but should be translated a bit differently. Or when you have way too many translations in a single default.po file and would like to split them somehow. That’s when domains can come in really handy. 

Gettext supports multiple domains out of the box. All you have to do is utilize the dgettext function, which works nearly the same as gettext. The only difference is that it accepts the domain name as the first argument. For instance, let’s introduce a notification domain to, well, display notifications. Add three more lines of code to the demo/lib/demo_web/templates/page/index.html.eex file:

Now we need to create new POT and PO files:

After the script finishes doing its job, notifications.pot as well as two notifications.po files will be created. Note once again that they are named after the domain. All you have to do now is add translation for the Russian language by modifying the priv/ru/LC_MESSAGES/notifications.po file:

What if you would like to pluralize a message stored under a given domain? This is as simple as utilizing a dngettext function. It works just like ngettext but also accepts a domain’s name as the first argument:

Conclusion

In this article, we have seen how to introduce internationalization in a Phoenix application with the help of Gettext. You have learned what Gettext is and what type of files it works with. We have this solution in action, have worked with PO and POT files, and utilized various Gettext functions.

Also we’ve seen a way to add support for multiple locales and added a way to easily switch between them. Lastly, we have seen how to employ pluralization rules and how to scope translations with the help of domains.

Hopefully, this article was useful to you! If you’d like to learn more about Gettext in the Phoenix framework, you may refer to the official guide, which provides useful examples and API reference for all the available functions.

I thank you for staying with me and see you soon!


Source: Nettuts Web Development

Creating a Blogging App Using Angular & MongoDB: Login

Angular is a one-stop framework for creating mobile and web apps using the same reusable code. Using Angular, you can divide the whole application into reusable components, which makes it easier to maintain and reuse code.

In this tutorial series, you’ll learn how to get started with creating a web app using Angular with MongoDB as the back end. You’ll be using Node.js for running the server.

Throughout the course of this tutorial, you’ll be building a blogging application using Angular, Node.js, and MongoDB. 

In this tutorial, you’ll see how to get started with setting up the application and creating the Login component.

Getting Started

Let’s get started by installing the Angular CLI.

Once you have installed the Angular CLI, create a project folder called AngularBlogApp

From the project folder, create a new Angular app using the following command:

Once you have the client app created, navigate to the project folder and install the required dependencies using Node Package Manager (npm).

Start the client server using npm.

You should have the application running at http://localhost:4200/.

Setting Up the Application

Your Angular web app will have a root component. Create a folder called root inside the src/app folder. Create a file called root.component.html and add the following HTML code:

Add a file called root.component.ts and add the following code:

Remove the files app.component.html, app.component.ts, app.component.scss, and app.component.spec.ts. You will have only one file called app.module.ts inside the src/app folder.

Import the RootComponent inside the app.module.ts file.

Include the RootComponent in the ngModules and bootstrap it.

Save the changes and restart the server. You will have the RootComponent displayed when the application loads.

You’ll be using Angular Router for routing in our blogging app. So import routing-related dependencies in a new file called app.routing.ts inside the src/app folder.

Define the route path along with the components as shown:

Export the routes to create a module with all route providers.

Here is how the app.routing.ts file looks:

As seen in the above code, you haven’t yet created the LoginComponent. It’s been added for the sake of clarity.

Import the ROUTING class in the app.module.ts file. 

Include it in the NgModule imports.

Place RouterOutlet in the root.component.html page. This where the route’s component gets rendered.

Create a folder called login inside the src/app folder. Inside the login folder, create a file called login.component.ts and add the following code:

Create a file called login.component.html and add the following code:

Save the above changes and restart the server. As the per the routes defined when the application loads the LoginComponent will get displayed.

Login Component -  Blogging App

Creating the Login Component

You already laid the foundation for the LoginComponent while setting up the application. Let’s create the view for the LoginComponent using Bootstrap.

Download and include the bootstrap CSS style in the assets folder and include the reference in the src/index.html page.

Place a wrapper around the app-root in the index.html page.

Add the following HTML to the login.component.html page.

Create a file called login.component.css inside the login folder and add the following CSS style.

Modify the @Component decorator to include the CSS style.

Save the above changes and try loading the application. You will have the LoginComponent displayed with the login view.

Login Screen Angular Blogging App

Creating the Login Service

LoginComponent will need to interact with the database to see if the logged-in user is valid or not. So it will need to make API calls. You’ll keep the database interaction portion in a separate file called login.service.ts.

Create a file called login.service.ts and add the following code:

Import the LoginService in the LoginComponent and add it as a provider in the component decorator. 

Add a method called validateLogin in the login.service.ts file which will make the API call. Here is how it looks:

As seen in the above code, it returns an observable which will be subscribed in the login.component.ts file. Here is how the login.service.ts file looks:

Implementing User Login Validation

Add the ngModel directive to the input elements in login.component.html.

Add a click event to the sign in button.

Here is how the modified login.component.html looks:

Define and initialize the user variable in the login.component.ts file.

The User model has been defined in the src/app/models folder. Here is how it looks:

Define a method called validateLogin which will be called on button click. Here is how the method looks:

When both username and password have been entered, the validateLogin method subscribes to the LoginService method to validate the user login.

Here is how the login.component.ts file looks:

Wrapping It Up

In this part of the Angular blogging app tutorial series, you saw how to get started with creating a web app using Angular. You created the basic structure of the Angular app and created the LoginComponent which will enable the user to validate the username and password. 

In the next part of the tutorial series, you’ll write the REST API for user login validation and create the home component.

Source code from this tutorial is available on GitHub.

Do let us know your thoughts and suggestions in the comments below.


Source: Nettuts Web Development

Creating Your First Angular App: Implement Routing

Before going ahead with this tutorial, it is a good idea to summarize everything we have done so far in order to avoid any confusion and errors. If you have missed any of the steps from the last three tutorials, it is a good idea to go back and make the necessary changes.

In the second tutorial, we created three different files named country.ts, country-data.ts, and country.service.ts. The country.ts file is used to store the Country class definition so we can import it to different files. The country-data.ts file is used to store an array named COUNTRIES

This array stores all the country objects that we want to display inside our app. The country.service.ts file is used to define a CountryService class with all the methods that we are going to use to access the information about different countries in one place. The methods of the CountryService class are used to get the top countries based on criteria like population and area or find information about a country with given name.

In the third tutorial, we created the HomeComponent for our app. This was done with the help of three different files named home.component.ts, home.component.html, and home.component.css. The home.component.ts file contained the definition of the HomeComponent class with different methods and properties to access and store information about all countries. 

The methods inside the HomeComponent class relied on the methods defined in country.service.ts to get all the data. The home.component.html file is used to store the template which will be used when displaying all the data accessed by methods defined in the home.component.ts file. The home.component.css file is used to provide different style rules which will control the appearance of different elements inside our template.

In the fourth tutorial, we created two more components for our app. For the AllCountries component, we created files named all-countries.component.tsall-countries.component.html, and all-countries.component.css. For the CountryDetail component, we created files named country-detail.component.ts, country-detail.component.html, and country-detail.component.css. Just like the HomeComponent, the .ts files contained the logic for our components, the .html files contained the template, and the .css files contained different rules that were applied to the elements in the template files.

In this tutorial, we will be implementing routing in our app. This way, the users will be able to navigate from one component to another with ease.

Modifying the Application Shell

Now, we just need to make changes to the application shell for our app to start working. The app.component.ts file will stay exactly the same as it was in the first tutorial.

However, we will be making changes to the app.component.html file. The HTML file should now have the following code:

Earlier, we were only showing the title of the app. Now, we have also added navigation to the template. The routerLink directive is used to provide links to different sections or pages of your app. Angular determines the component that it needs to display with the help of the routerLink directive. The position where those components are rendered is controlled using routerOutlets. The components are rendered after the router-outlet tags.

After creating the template file, we will add the following CSS to app.component.css to style the navigation links and the heading:

Now we will be telling Angular which components need to be rendered for a particular route or path. Create a file named app-routing.module.ts inside the src/app directory and put the following code in it:

We begin by importing all the necessary dependencies, including the components that we want to render for different routes. After that, we specify different paths and the components that should be rendered when users visit those paths. You can also redirect paths, as we did for this country information app. Whenever users visit http://localhost:4200/, they will be redirected to http://localhost:4200/home. Please keep in mind that specifying redirect routes requires you to specify a value for the pathMatch property to tell the router how it should match a URL to the path of any route.

If users visit http://localhost:4200/all-countries, we will render AllCountriesComponent after the router-outlet tag inside the app.component.html file to display a list of all countries.

We have used the routerLink directive inside the templates for AllCountriesComponent as well as HomeComponent to provide a link which users can click on to read more about any country. The value of routerLink for each country rendered within those templates follows the format routerLink="/detail/{{country.name}}". The value of the path property for rendering CountryDetailComponent has been specified as detail/:name, keeping the value of the routerLink directive in mind. The :name part in that path is used to identify the name of the country.

Updating the app.module.ts File

The last thing that we need to do in order to have a fully functioning Angular app is update the app.module.ts file. If you open this file in a text editor, you will notice that all three components that we generated using the Angular CLI have been already imported inside the file. Before we make any changes, your app.module.ts file should have the following code:

There are only two changes that we need to make to the app.module.ts file. First, we have to import the AppRoutingModule class from the app-routing.module.ts file that we created in the previous section. Second, add the class to the @NgModule.providers array. After these changes, your app.module.ts file should look like this.

If you move to your project directory and type the following command in the console, your app will load and render the HomeComponent.

You can click on various country blocks or the navigation links to load different components.

Final Thoughts

In this series, I wanted to teach readers who have never used Angular before how to create a basic Angular app. The app started functioning properly only after we completed our last tutorial. This was intentional because I wanted to avoid moving back and forth between the same files making changes that would need to be overridden in later tutorials. This could be very confusing for a beginner, so we just made all the changes to a file at once.

For practice, you can try creating more components which display the information about the countries in a different format. 

Furthermore, if it’s not clear, JavaScript has become one of the de facto languages of the web. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as Angular has demonstrated in this tutorial. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato Market.

If you have any questions related to this or any other tutorial of the series, please feel free to comment.


Source: Nettuts Web Development

Persisted WordPress Admin Notices: Part 4

So far in this series, we’ve covered two separate ways to dismiss persistent WordPress admin notices. We’ll build on that in this fourth and final part of the tutorial series by looking at two more specific methods to permanently dismiss your admin notices. We’ll round things off by showing how to create your own custom admin notice types and add decorations such as icons.

Sticky Admin Notice

We already know how to display an admin notice that can be dismissed. All we have to do is add the is-dismissible CSS class to the containing div element. However, this is only temporary and will only dismiss the notice for the current page. As soon as the page reloads, it reappears again.

To make it permanently dismissible involves more code than we’ve seen so far, but it isn’t too difficult to implement. Let’s take a look at what’s involved, starting with an overview.

We’ll use a custom option to store the display status of our admin notice. On plugin activation, this option will be created/updated and set to true. The admin notice will then only display if the option is currently true.

The key to this method is using Ajax to allow us to set the option to false when the dismiss button is clicked. Once successfully set to false, the conditional code that checks the option status will fail, and the admin notice will no longer be displayed.

Let’s begin by adding the admin notice itself, which will be a plain notice to begin. In Gwyer_Dismissible_Admin_Notices::init(), add a new add_action call:

Then add the dismiss_admin_notice() callback function to the same class:

This adds an admin notice that displays only on the plugin admin page and is very similar to what we’ve seen in previous tutorials. The only slight difference here is that we’ve also added a CSS ID to the admin notice div container. This will be used to specifically target the admin notice we’re interested in.

Standard admin notice with custom CSS ID

We’ll need to add JavaScript code to make the Ajax call work, so add a js folder in the root admin-notices plugin folder and inside create a file called admin-notices.js. Add code to the new file to test it’s loading properly by outputting a console message.

In Gwyer_Plugin_Options::init(), add a new add_action call to enqueue our script file:

We only want this JavaScript file to be loaded on the plugin options page, so we need a way to conditionally enqueue it. We can do this by checking what admin page we’re currently on to see if it’s our plugin options page.

We can get a handle to our plugin options page by storing the return value of add_options_page() in a class property. We had no need of this value previously, so we just called add_options_page() without storing the return value.

Add a class property to Gwyer_Plugin_Options:

Then, in create_admin_menu_page(), use this new property to store the handle to our plugin options page:

We can finally enqueue our JavaScript file so that it loads only on the plugin options page:

If all went well then you’ll see an admin-notices.js loaded! message outputted to the browser console.

Admin notice JavaScript loaded

Update the JavaScript code in admin-notices.php to the following:

Here, we’re listening for a click event on the an1 CSS ID we added to our admin notice earlier. As soon as it’s clicked, an Ajax request is fired. Let’s handle that request next.

In Gwyer_Dismissible_Admin_Notices::init(), add a new add_action call:

This will run the callback function once the display_dismissible_admin_notice Ajax request fires. Remember that this originally was defined as the data.action property in our Ajax request.

Now add the display_dismissible_admin_notice callback function to Gwyer_Dismissible_Admin_Notices:

Save your changes, reload the plugin options page, and click the admin notice dismiss button to see the Ajax request in action!

The Ajax request in action

If the request was successful then you’ll see a Processing Ajax request… DONE! message displayed in the browser console.

The final piece of the puzzle is to create a custom option initially set to true but which is then set to false when the dismiss button is clicked. Then, when the plugin options page loads, the admin notice only displays if the custom option value is true.

In Gwyer_Dismissible_Admin_Notices::init(), add a second call to register_activation_hook():

And add the create_custom_option callback function to the class:

Now, when the plugin is activated, a custom option called gwyer-dismiss is created and set to true.

Update display_dismissible_admin_notice() to update our custom option when the Ajax request fires:

Now all that’s left to do is update dismiss_admin_notice() to check for the value of the custom option and only render the admin notice if it is set to true.

Deactivate and reactivate the plugin to test the code we’ve added. Visit the plugin options page, dismiss the admin notice, and refresh the page. The notice should no longer be visible. Yay!

Because the custom option is set to true every time the plugin is activated, you can repeat the above steps to test the dismissible admin notice as many times as you like.

To keep things simple, this was a bare-bones example of using an Ajax request to set the custom admin notice option. In practice, you’d want to use a nonce (number used once) value to validate the Ajax request as a minimum security measure.

This was a lot of work to just permanently dismiss an admin notice, but the final effect works well and is something you can use to good effect in your own plugins.

Custom Action Admin Notice Dismissal

It’s time to look at a slightly different method for dismissing admin notices now. This is a nag type of admin notice that displays on all admin screens and can’t be dismissed until some action has been performed.

Note: Use this method with caution or you’ll risk alienating your plugin users very quickly!

The specific action we’ll focus on in our example will be to display an admin notice until a required plugin or list of plugins have been installed and activated.

Unlike the previous method where we had to jump through hoops to get an admin notice to be permanently dismissible, the solution for this method is refreshingly simple!

First, comment out all the function calls in Gwyer_Dismissible_Admin_Notices::init(). Then, add a new add_action() function:

And define the callback as follows:

That’s all there is to it! I told you it was simple, didn’t I?

The only thing we did differently this time was to use the is_plugin_active() WordPress function to test if the Hello Dolly plugin is installed and activated. If not, is_plugin_active() will return false, and our admin notice will be displayed.

Example of a nag admin notice

Try activating the Hello Dolly plugin to verify the admin notice goes away.

This works well for single plugins, but what if you wanted to remind users to activate multiple plugins? Instead of hard-coding in the Hello Dolly plugin information, we could create an array to whitelist our required plugins.

Replace install_plugin_to_dismiss_admin_notice() with:

The required plugins are now stored in an array which is looped over to check if each plugin has been activated. For any plugin not currently active, the name is added to a $requires_activating array which is outputted via the admin notice as a comma-separated list of required plugin names.

List of required plugins

Custom Admin Notices

Before we finish, let’s have a little fun by creating our own custom admin notice types. Let’s see how to add some custom admin notice types of our own. By now you’ll be fully familiar with the four built-in admin notices WordPress provides by default, but it’s not that difficult to come up with some of our own.

First, though, comment out all function calls in Gwyer_Dismissible_Admin_Notices::init() so we start out on a clean slate.

We’ll need to add CSS for our custom admin notice types, so in the root plugin folder add a css folder, and inside create a file called admin-notices.css. To enqueue it on all admin pages, add a new add_action call in Gwyer_Plugin_Options::init().

Then, for the enqueue_styles() callback, add this method to the same class:

Now let’s set up a new method to output our custom admin notices. In Gwyer_Admin_Notices::init(), add:

Then add a callback to display a series of custom admin notices:

Finally, add CSS to admin-notices.css to style our custom admin notices:

After you save the changes, load any admin page to see our custom admin notices.

Some examples of custom admin notices

Judging by the results, it’s probably a good idea to use custom admin notices sparingly, otherwise you’ll run the risk of them looking garish. 

I won’t go into details about the custom CSS used. It’s just for a bit of fun, and most of the styling is pretty self-explanatory.

We used dashicons font icons for our custom admin notices for convenience as they are available in the WordPress admin by default. But you could import and use any icons you like for extra decoration.

Try the Code for Yourself

All the code from this tutorial series has been wrapped up in a WordPress plugin for you to download. Take a look at the code, extend it, and implement new ways to display (and dismiss) admin notices. Be sure to let me know in the comments if you create something cool! I’d love to see what you come up with.

Conclusion

Thank you for joining me in this four-part tutorial series. Hopefully you’ll now have a lot more confidence in how you implement admin notices in your own projects.

We’ve covered many different aspects of WordPress admin notices, including multiple ways of permanently dismissing them, which isn’t possible without custom code.

Creating your own custom admin notices is pretty easy too, but in practice you’d want to use them sparingly in your own projects. Most of the time it’s best to keep to the default WordPress styles for a consistent user experience.

WordPress has an incredibly active economy. There are themes, plugins, libraries, and many other products that help you build out your site and project. The open-source nature of the platform also makes it a great option from which you can better your programming skills. Whatever the case, you can see what we have available in the Envato Market.

And don’t forget to download the plugin and play around with the code. It’s a great way to get more familiar with how all the pieces fit together. And please let me know your thoughts on the tutorial via the comments below.


Source: Nettuts Web Development

Creating Your First Angular App: Components, Part 2

In the third tutorial of the series, you learned how to create the HomeComponent of your country information app. We will create two more components in this tutorial. One of the components will list all the countries that we have stored in the COUNTRIES array. Another component will display the details of any country selected by the user.

Creating the AllCountriesComponent

The HomeComponent that we created in the previous tutorial and the AllCountriesComponent that we will create in this section are very similar. The only difference is that instead of sorting the COUNTRIES array and slicing it to only get the first three countries, we will be listing all of them at once. Inside the console, move to your project directory and run the following command:

This will create a folder named all-countries inside the src/app directory of your Angular app. The folder will have three different files named all-countries.component.ts, all-countries.component.html, and all-countries.component.css. The component logic like getting the list of countries and initializing the component itself will go inside the .ts file. The .html file will store the template for the component, and the .css file will store different CSS rules to style the template.

Here is the code for the all-countries.component.ts file:

As you can see, the code is pretty basic. We import the Country and CountryService classes that we created in the second tutorial of the series. The component decorator is used to specify the selector that we will be using to identify the AllCountriesComponent.

Inside the class definition, we create a countries property that accepts an array of Country objects as its value. The CountryService class is added to the component using dependency injection. We call the getCountries() method of this class upon initialization. The getCountries() method itself relies on getCountries() from the CountryService class, which returns an array of Country objects.

The all-countries.component.html file will store the template for our component.

Just like the template for HomeComponent, we are using *ngFor to list all the countries obtained by the getCountries() method and stored in the countries property of the AllCountriesComponent class. We use this component to display the capitals of different countries using the capital property. You will learn about the routerLink directive used with the a tag in the next tutorial.

The CSS used is the same as that of the home.component.css file. The only difference is that we change the background color for each country block to green. Here is the complete CSS code:

Creating the CountryDetailComponent

The CountryDetailComponent will be the third and final component of our Angular app. Whenever users click on the name of any country listed inside either the HomeComponent or AllCountriesComponent, they will be taken to the CountryDetailComponent.

Go back to the console and run the following command:

This will create a folder named country-detail inside the src/app directory of your app. You should see four different files inside the folder. Three of those files will be named: country-detail.component.ts, country-detail.component.html, and country-detail.component.css. Just like the earlier components, country-detail.component.ts will contain the logic of our component, and country-detail.component.html will contain the template to render it.

Here is the code for the country-detail.component.ts file:

This time, we have also imported ActivatedRoute and Location, along with Component and OnInit. We use ActivatedRoute to access information about a route associated with a component loaded in an outlet. We use Location to enable our application to interact with the browser’s URL.

Inside the class definition, we create a property named country which accepts a Country object as its value. Unlike HomeComponent and AllCountriesComponent, the CountryDetailComponent class has to show details of only one country at a time.

The getCountry() method extracts the name parameter from the route snapshot and uses the value to find a country with the given name inside the COUNTRIES array. The goBack() method takes the user back to the previous page with the help of the back() method from the Location class.

Here is the code for the country-detail.component.html file:

The template code inside the div with *ngIf="country" is rendered only if country has been set to a value. We are using Angular pipes to capitalize the name of the country and properly format the area and population of the countries. We are binding the click event of our Go Back button to the goBack() method of our component so that whenever users click on a button, they are taken back to the previous page.

Here is the CSS that will go inside the country-detail.component.css file:

Final Thoughts

With the completion of this tutorial, we have added two more components to our first Angular app. The AllCountriesComponent was very similar to the HomeComponent as they both rendered a list of countries stored in the COUNTRIES array. The CountryDetailComponent was different because it extracted information about a single country from the COUNTRIES array based on its name. 

After creating three different components, you should now have a basic understanding of the interactions between .ts, .html, and .css files to create a fully functioning component.

In the next tutorial of the series, you will learn how to use all these components together and make some final changes so that the app can run without any errors.


Source: Nettuts Web Development