<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akshita Dixit</title>
    <description>The latest articles on DEV Community by Akshita Dixit (@akshitadixit).</description>
    <link>https://dev.to/akshitadixit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F533001%2F85ed09d6-6943-4a46-8191-a477cdec4575.jpeg</url>
      <title>DEV Community: Akshita Dixit</title>
      <link>https://dev.to/akshitadixit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akshitadixit"/>
    <language>en</language>
    <item>
      <title>Creating a Chatroom in Angular using Amplication</title>
      <dc:creator>Akshita Dixit</dc:creator>
      <pubDate>Thu, 20 Jul 2023 15:34:06 +0000</pubDate>
      <link>https://dev.to/akshitadixit/creating-a-chatroom-in-angular-using-amplication-39l</link>
      <guid>https://dev.to/akshitadixit/creating-a-chatroom-in-angular-using-amplication-39l</guid>
      <description>&lt;p&gt;Angular is a stunningly powerful web framework that combines design and development seamlessly, enabling developers to create captivating web applications with elegance and precision. Its extensive features and modular structure empower creativity and deliver exceptional user experiences.&lt;/p&gt;

&lt;p&gt;Amplication is an open-source platform that simplifies the process of building backend servers for your applications. It provides developers with tools for building scalable, maintainable, and secure applications. Amplication generates a backend server based on a data model defined by the developer. It also supports GraphQL and REST APIs, allowing developers to create flexible and modern applications.&lt;/p&gt;

&lt;p&gt;In this article, we will discuss how to create a chatroom in Angular using Amplication. We will cover the prerequisites, getting started, creating and utilizing the backend server, creating the Angular UI, and running the app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pre-requisites
&lt;/h1&gt;

&lt;p&gt;Node.js and npm (Node Package Manager): Amplication generates a Node.js and NestJS code. To run your own server, you will need npm installed. Head over to download Node, which comes with npm from the given link &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;https://nodejs.org/en/download/&lt;/a&gt;&lt;br&gt;
Docker: The server created by Amplication will execute a Docker container running PostgreSQL that is required to develop or test a Node.js application. Docker is required to provide an isolated and reproducible environment for running the database service. Head over to the Docker and follow the steps to install it locally. You can find that here &lt;a href="https://www.docker.com/get-started/" rel="noopener noreferrer"&gt;https://www.docker.com/get-started/&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  🌟 Help us reach new heights! Give Amplication your star on GitHub! 🌟
&lt;/h2&gt;

&lt;p&gt;Welcome to this exciting tutorial on creating a chatroom in Angular using Amplication! We're thrilled to embark on this journey together. But before we dive into the world of real-time communication, we have a special request for you. Just like stars illuminate the night sky, your stars can brighten our day and show your appreciation for the incredible work done by the Amplication team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/amplication/amplication" rel="noopener noreferrer"&gt;https://github.com/amplication/amplication&lt;/a&gt;&lt;/p&gt;


&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2Fplease.gif" alt=""&gt;




&lt;p&gt;We invite you to visit the Amplication GitHub repository and give us your star. It's a simple yet powerful gesture that helps us gain recognition and motivation to deliver even better open-source solutions. Here's the exciting part: we're only a few stars away from reaching the remarkable milestone of 11,000 stars on GitHub!&lt;/p&gt;

&lt;p&gt;Join us in creating something extraordinary with Amplication. Click that star button on GitHub and help us soar to new heights. Together, let's make Amplication shine! ✨&lt;/p&gt;
&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;To begin, navigate to Amplication's website at &lt;a href="https://app.amplication.com/login" rel="noopener noreferrer"&gt;https://app.amplication.com/login&lt;/a&gt; and log in using your GitHub account.&lt;br&gt;
After login for the first time, you will be directed to the service creation wizard. Follow the steps and complete the wizard to create your service's basic structure, such as naming your service, connecting your GitHub Repository, and selecting a repo style (Monorepo or Polyrepo). You can follow the steps here for more details here &lt;a href="https://docs.amplication.com/first-service/" rel="noopener noreferrer"&gt;https://docs.amplication.com/first-service/&lt;/a&gt;.&lt;/p&gt;


&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F0.png" alt=""&gt;




&lt;p&gt;The next step is to add entities to your database.&lt;/p&gt;

&lt;p&gt;In the context of Amplication, an entity is a high-level representation of a data model that maps to a database table in SQL or a collection in NoSQL. Essentially, an entity is a blueprint for a specific type of data object that will be stored in your application's database.&lt;/p&gt;

&lt;p&gt;Entities consist of fields, representing the different data pieces that make up an object of that entity type. For example, in the case of the "User1", the fields might include "id," "alias," "message," and so on, depending on the specific requirements of the application.&lt;/p&gt;

&lt;p&gt;To do this, navigate to the "Entities" section and click on "Add Entity," giving it a meaningful name. We will add two fields for out use case, "alias" and "message".&lt;/p&gt;


&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F2.png" alt=""&gt;





&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F4.png" alt=""&gt;




&lt;p&gt;You can commit changes to your GitHub repository with your entities set up. Amplication will create a pull request in your repository for you to review and merge. Once the pull request is merged, the backend server is ready to run and you can begin creating the frontend using Angular.&lt;/p&gt;

&lt;p&gt;Now, navigate to your GitHub repository and clone it locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone &amp;lt;git-url&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get started, navigate to the server director in your freshly cloned repository and run the following commands: You may find the server directory under &lt;code&gt;apps/&amp;lt;servicename-service&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --force
npm run prisma:generate

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands will install any necessary dependencies and generate the Prisma client.&lt;br&gt;
Next, start the PostgreSQL using Docker by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run docker:db

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Docker is running, initialize the database by entering the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run db:init

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have confirmed that everything is set up correctly, you can start the server by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amplication also provides the UI to test your REST API endpoints. This includes a useful built-in functionality that allows you to send requests to your API directly within the page. To use this feature, select any endpoint and click “Try it out”. This will provide you with fields to add headers, and upon execution, you will also receive a curl request that you can run from your terminal or import into Postman to try it out. This feature is helpful when understanding the structure of your response and debugging errors.&lt;br&gt;
To test this out, switch to the admin-ui folder and run the Admin UI panel by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --force | npm start

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Admin UI panel is now up and running at &lt;a href="http://localhost:3001/" rel="noopener noreferrer"&gt;http://localhost:3001&lt;/a&gt;. Additionally, you can find a complete list of REST API endpoints at &lt;a href="http://localhost:3000/api/" rel="noopener noreferrer"&gt;http://localhost:3000/api/&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating Angular UI
&lt;/h1&gt;

&lt;p&gt;Let's start by creating an Angular application. Angular comes with the all-powerful CLI, enabling us to seamlessly create applications, workspaces, pipes, and services, reducing development times.&lt;/p&gt;

&lt;p&gt;Now within your repository, run the following command to create an Angular Application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new your-app-name

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the command, you will be prompted to choose various options such as routing and styling format. You can make selections based on your project requirements or simply press Enter to choose the default options.&lt;br&gt;
For this application, we will be using SCSS pre-processor and Component Nesting.&lt;br&gt;
Next, create the chatroom component using the following command from the CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng g c chatroom

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where g is a short-hand notation for &lt;code&gt;generate&lt;/code&gt; and c for &lt;code&gt;component&lt;/code&gt;. This same command can also be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component chatroom

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate the chatroom.component.ts where we will write your TypeScript logic, the chatroom.component.html where we will define the basic structure of our chatroom, the &lt;code&gt;chatroom.component.scss&lt;/code&gt; where we will style our classes and the chatroom.component.spec.ts where we will write a test to verify our logic.&lt;/p&gt;

&lt;p&gt;This also updates the app.module.ts file for us with the required imports while bootstrapping the Angular Application.&lt;/p&gt;

&lt;p&gt;Let's start by creating the popup, which asks for a user alias and authenticates each login by generating a unique JSON Web Token. The API to generate the JWT is included within the Amplications endpoints and can be tested via the Admin UI. We will need this JWT to authenticate each of our API calls. This is also what will distinguish what message was sent by which user when n-number of users join our online chatroom, some likely with similar names.&lt;/p&gt;

&lt;p&gt;Now, in the chatroom.component.ts itself, we will create a new component for the sake of modularity. We will call this the &lt;code&gt;dialog-popup&lt;/code&gt; Component.&lt;/p&gt;

&lt;p&gt;Since the template for this component is fairly small, we will add the HTML within the template property itself and will add the same stylesheet path as the one we will use for the chatroom Component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'dialog-popup',
  template: `
    &amp;lt;div class="dialog-popup-container"&amp;gt;
    &amp;lt;h2 class="dialog-popup-title"&amp;gt;Welcome to the Chatroom!&amp;lt;/h2&amp;gt;
    &amp;lt;p class="dialog-popup-message"&amp;gt;Please enter your alias:&amp;lt;/p&amp;gt;
    &amp;lt;input type="text" [(ngModel)]="alias" class="dialog-popup-input" placeholder="Alias"&amp;gt;
    &amp;lt;button (click)="saveAlias()" class="dialog-popup-button"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `,
  styleUrls: ['./chatroom.component.scss']
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's define the &lt;code&gt;DialogPopupComponet&lt;/code&gt; class. We will use the OnInit lifecycle hook that is called after Angular has initialized all data-bound properties of a directive since we want to show this popup as soon as the application is bootstrapped.&lt;br&gt;
We will inject the HTTP client as dependency Injection as we need to make API Calls to authenticate every user and generate a corresponding JWT Token.&lt;br&gt;
We will also use MatDialogRef as a Dependency Injection to create the popup using material UI.&lt;br&gt;
Do use Angular Material, and add this dependency using the powerful Angular CLI. Run the following command in the root directory of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng add @angular/material

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will then be allowed to make certain decisions for your customization such as selecting a pre-built theme or making a custom theme, using Typography styles and Add Aminations.&lt;/p&gt;

&lt;p&gt;At the end of this, you’ll see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ℹ Using package manager: npm
✔ Found compatible package version: @angular/material@15.2.9.
✔ Package information loaded.

The package @angular/material@15.2.9 will be installed and executed.
Would you like to proceed? Yes
✔ Packages successfully installed.
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink        [ Preview:
&amp;lt;https://material.angular.io?theme=indigo-pink&amp;gt; ]
? Set up global Angular Material typography styles? Yes
? Include the Angular animations module? Include and enable animations
UPDATE package.json (1101 bytes)
✔ Packages installed successfully.
UPDATE src/app/app.module.ts (569 bytes)
UPDATE angular.json (2998 bytes)
UPDATE src/index.html (572 bytes)
UPDATE src/styles.scss (181 bytes)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to import the necessary header files from @angular/common and angular/material&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { HttpClient, HttpHeaders } from '@angular/common/http';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, remember to add this component to the declarations array of app.module.ts. And the &lt;code&gt;HttpClientModule&lt;/code&gt; and &lt;code&gt;MatDialog&lt;/code&gt; Module to the imports array. We have also used the &lt;code&gt;titleCase&lt;/code&gt; pipe in this example to beautify the output. Include such pipes in the Providers array though this step is optional.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;app.module.ts&lt;/code&gt; should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NgModule } from '@angular/core';
import { TitleCasePipe } from '@angular/common'
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ChatroomComponent } from './chatroom/chatroom.component';
import { FormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material/dialog';
import { DialogPopupComponent } from './chatroom/chatroom.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    ChatroomComponent,
    DialogPopupComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    MatDialogModule,
    HttpClientModule
  ],
  providers: [TitleCasePipe],
  bootstrap: [AppComponent]
})
export class AppModule { }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your class should look something like this after the dependency injection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class DialogPopupComponent implements OnInit {
  alias: string = '';

  constructor(
    private dialogRef: MatDialogRef&amp;lt;DialogPopupComponent&amp;gt;,
    private http: HttpClient,
    ) { }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to define the &lt;code&gt;ngOnInit()&lt;/code&gt; method. This comes from the OnInt Interface which enables us to handle additional initialization tasks.&lt;br&gt;
Here we check if the localStorage has a JWT. In such a case we can close the popup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ngOnInit() {
    const hasShownPopup = localStorage.getItem('shownPopup');
    if (hasShownPopup) {
      this.dialogRef.close();
    }
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define a function to save the alias the current user enters and generate a JWT corresponding to it.&lt;br&gt;
We define the body object of the API call. In our case, a username and password will be needed to generate a JWT. The response to this POST request will contain an accessToken, the JSON Web Token. We store this in the token variable in the &lt;code&gt;localStorage&lt;/code&gt; for future use. If the alias already exists or the JWT is successfully done we close the dialog box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;saveAlias() {
    if (this.alias) {
      localStorage.setItem('userAlias', this.alias);
      // localStorage.setItem('shownPopup', 'true');

      const body = {
        username: 'admin',
        password: 'admin'
      };

      this.http.post('&amp;lt;http://localhost:3000/api/login&amp;gt;', body).subscribe(
        (response: any) =&amp;gt; {
          // Handle the response here
          const token = response.accessToken;
          // Do something with the token, such as storing it in localStorage
          localStorage.setItem('jwtToken', token);

          // Close the dialog
          this.dialogRef.close(this.alias);
        },
        (error: any) =&amp;gt; {
          // Handle any error that occurred during the API call
          console.error('Error:', error);
        }
      );

      this.dialogRef.close(this.alias);
    }
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end, the &lt;code&gt;dialog-popup&lt;/code&gt; component should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'dialog-popup',
  template: `
    &amp;lt;div class="dialog-popup-container"&amp;gt;
    &amp;lt;h2 class="dialog-popup-title"&amp;gt;Welcome to the Chatroom!&amp;lt;/h2&amp;gt;
    &amp;lt;p class="dialog-popup-message"&amp;gt;Please enter your alias:&amp;lt;/p&amp;gt;
    &amp;lt;input type="text" [(ngModel)]="alias" class="dialog-popup-input" placeholder="Alias"&amp;gt;
    &amp;lt;button (click)="saveAlias()" class="dialog-popup-button"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `,
  styleUrls: ['./chatroom.component.scss']
})
export class DialogPopupComponent implements OnInit {
  alias: string = '';

  constructor(
    private dialogRef: MatDialogRef&amp;lt;DialogPopupComponent&amp;gt;,
    private http: HttpClient,
    ) { }

  ngOnInit() {
    const hasShownPopup = localStorage.getItem('shownPopup');
    if (hasShownPopup) {
      this.dialogRef.close();
    }
  }

  saveAlias() {
    if (this.alias) {
      localStorage.setItem('userAlias', this.alias);
      // localStorage.setItem('shownPopup', 'true');

      const body = {
        username: 'admin',
        password: 'admin'
      };

      this.http.post('&amp;lt;http://localhost:3000/api/login&amp;gt;', body).subscribe(
        (response: any) =&amp;gt; {
          // Handle the response here
          const token = response.accessToken;
          // Do something with the token, such as storing it in localStorage
          localStorage.setItem('jwtToken', token);

          // Close the dialog
          this.dialogRef.close(this.alias);
        },
        (error: any) =&amp;gt; {
          // Handle any error that occurred during the API call
          console.error('Error:', error);
        }
      );

      this.dialogRef.close(this.alias);
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the popup-dialog component is ready let's create the chatroom component and add some styles.&lt;/p&gt;

&lt;p&gt;Start by defining some instance variables, alias - of type String to store the alias name of the currently logged-in user, messages - of string[] to store the complete list/array of messages in the chatroom, and a message - of type string to store the current message sent to the backend using the Amplication generated APIs.&lt;/p&gt;

&lt;p&gt;We will also use the &lt;code&gt;MatDialog&lt;/code&gt; and &lt;code&gt;HttpClient&lt;/code&gt; as dependent injection in the constructor of this class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'app-chatroom',
  templateUrl: './chatroom.component.html',
  styleUrls: ['./chatroom.component.scss']
})
export class ChatroomComponent implements OnInit {
  alias: string = '';
  messages: string[] = [];
  message: string = '';
  isCurrentUser: boolean = false;

  constructor(
    public dialog: MatDialog,
    public http: HttpClient
    ) { }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next let's create the &lt;code&gt;openDialog&lt;/code&gt; and &lt;code&gt;showPopupBox&lt;/code&gt; methods which will primarily function to render a dialog box of our desired size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;showPopupBox() {
    this.openDialog();
  }

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogPopupComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result =&amp;gt; {
      if (result) {
        this.alias = result;
        // localStorage.setItem('userAlias', this.alias);
      }
    });
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a method that sends a message to the backend and adds this to the message array. First, &lt;code&gt;getItem - userAlias&lt;/code&gt; and JWT from the local storage as we must pass this in the header of our API Call. Ultimately, we push the latest message to the messages array along with the alias name and then reset the message to ‘’.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sendMessage() {
    const userAlias = localStorage.getItem('userAlias');
    const token = localStorage.getItem('jwtToken');

    if (this.message) {
      const body = {
        alias: userAlias,
        message: this.message,
      };

      const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);

      this.http.post('&amp;lt;http://localhost:3000/api/user1s&amp;gt;', body, { headers }).subscribe(
        (response: any) =&amp;gt; {
          // set message
          console.log('Response:', response);
        },
        (error: any) =&amp;gt; {
          // Handle any error that occurred during the API call
          console.error('Error:', error);
        }
      );

      this.messages.push(`${this.alias}: ${this.message}`);
      this.message = '';
    }
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define the function where we receive the freshly sent message to the backend using Amplication-generated APIs. Here we fetch &lt;code&gt;userAlias&lt;/code&gt; and JWT from the localStorage and it in the headers of the GET API call.&lt;br&gt;
Now, we filter out and see if there is any new message. We only append to the message array the new messages we found in the previous filter. This helps us prevent rendering the same set of messages multiple times at every state change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recieveMessage() {
    const userAlias = localStorage.getItem('userAlias');
    const token = localStorage.getItem('jwtToken');

    const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);

    this.http.get('&amp;lt;http://localhost:3000/api/user1s&amp;gt;', { headers }).subscribe(
      (response: any) =&amp;gt; {
        // Check if new messages are found
        const newMessages = response.filter((message: any) =&amp;gt; {
          return !this.messages.includes(`${message.alias}: ${message.message}`);
        });

        // Add new messages to the messages array
        newMessages.forEach((message: any) =&amp;gt; {
          this.messages.push(`${message.alias}: ${message.message}`);
        });

        console.log('Response:', response);
      },
      (error: any) =&amp;gt; {
        // Handle any error that occurred during the API call
        console.error('Error:', error);
      }
    );
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At last, create the &lt;code&gt;ngOnInit&lt;/code&gt; method to call the &lt;code&gt;showPopupBox&lt;/code&gt; method as soon as the application is bootstrapped. Reset the messages array and &lt;code&gt;userAlias&lt;/code&gt; and JWT for any new user.&lt;/p&gt;

&lt;p&gt;We also listen actively, every 1000 milliseconds, for any message change by subscribing to an interval observable and calling the recieveMessage function here.&lt;/p&gt;

&lt;p&gt;Remember to import &lt;code&gt;rxjs&lt;/code&gt; to use the interval observable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { interval } from 'rxjs';

ngOnInit() {
    this.showPopupBox();

    this.messages = [];
    localStorage.removeItem('userAlias');
    localStorage.removeItem('jwtToken');

    interval(1000).subscribe(() =&amp;gt; {
      this.recieveMessage();
    });
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our &lt;code&gt;chatroom.component.ts&lt;/code&gt; is ready, it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { interval } from 'rxjs';

@Component({
  selector: 'app-chatroom',
  templateUrl: './chatroom.component.html',
  styleUrls: ['./chatroom.component.scss']
})
export class ChatroomComponent implements OnInit {
  alias: string = '';
  messages: string[] = [];
  message: string = '';

  constructor(
    public dialog: MatDialog,
    public http: HttpClient
    ) { }

  ngOnInit() {
    this.showPopupBox();

    this.messages = [];
    localStorage.removeItem('userAlias');
    localStorage.removeItem('jwtToken');

    interval(1000).subscribe(() =&amp;gt; {
      this.recieveMessage();
    });
  }

  showPopupBox() {
    // const userAlias = localStorage.getItem('userAlias');
    // if (userAlias) {
    //   this.alias = userAlias;
    // } else {
    //   this.openDialog();
    // }
    this.openDialog();
  }

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogPopupComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result =&amp;gt; {
      if (result) {
        this.alias = result;
        // localStorage.setItem('userAlias', this.alias);
      }
    });
  }

  sendMessage() {
    const userAlias = localStorage.getItem('userAlias');
    const token = localStorage.getItem('jwtToken');

    if (this.message) {
      const body = {
        alias: userAlias,
        message: this.message,
      };

      const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);

      this.http.post('&amp;lt;http://localhost:3000/api/user1s&amp;gt;', body, { headers }).subscribe(
        (response: any) =&amp;gt; {
          // set message
          console.log('Response:', response);
        },
        (error: any) =&amp;gt; {
          // Handle any error that occurred during the API call
          console.error('Error:', error);
        }
      );

      this.messages.push(`${this.alias}: ${this.message}`);
      this.message = '';
    }
  }

  recieveMessage() {
    const userAlias = localStorage.getItem('userAlias');
    const token = localStorage.getItem('jwtToken');

    const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);

    this.http.get('&amp;lt;http://localhost:3000/api/user1s&amp;gt;', { headers }).subscribe(
      (response: any) =&amp;gt; {
        // Check if new messages are found
        const newMessages = response.filter((message: any) =&amp;gt; {
          return !this.messages.includes(`${message.alias}: ${message.message}`);
        });

        // Add new messages to the messages array
        newMessages.forEach((message: any) =&amp;gt; {
          this.messages.push(`${message.alias}: ${message.message}`);
        });

        console.log('Response:', response);
      },
      (error: any) =&amp;gt; {
        // Handle any error that occurred during the API call
        console.error('Error:', error);
      }
    );
  }
}

@Component({
  selector: 'dialog-popup',
  template: `
    &amp;lt;div class="dialog-popup-container"&amp;gt;
    &amp;lt;h2 class="dialog-popup-title"&amp;gt;Welcome to the Chatroom!&amp;lt;/h2&amp;gt;
    &amp;lt;p class="dialog-popup-message"&amp;gt;Please enter your alias:&amp;lt;/p&amp;gt;
    &amp;lt;input type="text" [(ngModel)]="alias" class="dialog-popup-input" placeholder="Alias"&amp;gt;
    &amp;lt;button (click)="saveAlias()" class="dialog-popup-button"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `,
  styleUrls: ['./chatroom.component.scss']
})
export class DialogPopupComponent implements OnInit {
  alias: string = '';

  constructor(
    private dialogRef: MatDialogRef&amp;lt;DialogPopupComponent&amp;gt;,
    private http: HttpClient,
    ) { }

  ngOnInit() {
    const hasShownPopup = localStorage.getItem('shownPopup');
    if (hasShownPopup) {
      this.dialogRef.close();
    }
  }

  saveAlias() {
    if (this.alias) {
      localStorage.setItem('userAlias', this.alias);
      // localStorage.setItem('shownPopup', 'true');

      const body = {
        username: 'admin',
        password: 'admin'
      };

      this.http.post('&amp;lt;http://localhost:3000/api/login&amp;gt;', body).subscribe(
        (response: any) =&amp;gt; {
          // Handle the response here
          const token = response.accessToken;
          // Do something with the token, such as storing it in localStorage
          localStorage.setItem('jwtToken', token);

          // Close the dialog
          this.dialogRef.close(this.alias);
        },
        (error: any) =&amp;gt; {
          // Handle any error that occurred during the API call
          console.error('Error:', error);
        }
      );

      this.dialogRef.close(this.alias);
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now head over to the chatroom.component.html to add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="chatroom-container"&amp;gt;
    &amp;lt;div class="messages-container"&amp;gt;
      &amp;lt;div class="message" *ngFor="let msg of messages"&amp;gt;{{ msg | titlecase }}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="input-container"&amp;gt;
      &amp;lt;input type="text" [(ngModel)]="message" placeholder="Type a message..."&amp;gt;
      &amp;lt;button (click)="sendMessage()"&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are using Angular’s two-way data binding to update the message from the chatbox that the user enters.&lt;/p&gt;

&lt;p&gt;Now head over to &lt;code&gt;chatroom.component.scss&lt;/code&gt; to add some style to the chatroom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* chatroom.component.scss */

.chatroom-container {
    display: flex;
    flex-direction: column;
    height: 100%;
  }

  .messages-container {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
  }

  .message {
    background-color: #f2f2f2;
    padding: 8px;
    margin-bottom: 5px;
    border-radius: 4px;
  }

  .input-container {
    position: fixed;
    top: 90%;
    width: 90%;
    display: flex;
    align-items: center;
    margin-left: 8vb;
    padding: 10px;
    background-color: #f2f2f2;
  }

  .input-container input {
    flex: 1;
    margin-right: 10px;
    padding: 8px;
    border: none;
    border-radius: 4px;
  }

  .input-container button {
    padding: 8px 12px;
    background-color: #4caf50;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  /* dialog-popup.component.scss */

  .dialog-popup-container {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
  }

  .dialog-popup-title {
    font-size: 24px;
    margin-bottom: 10px;
  }

  .dialog-popup-message {
    font-size: 16px;
    margin-bottom: 10px;
  }

  .dialog-popup-input {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
  }

  .dialog-popup-button {
    padding: 8px 12px;
    margin: 8px 0;
    background-color: #4caf50;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  .user-bubble {
    background-color: #4caf50;
    padding: 8px;
    margin-bottom: 5px;
    border-radius: 4px;
  }

  .other-bubble {
    background-color: #f2f2f2;
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now head over to app.module.html and replace the boilerplate with the following component nesting using the selector of the chatroom Component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app-chatroom&amp;gt;&amp;lt;/app-chatroom&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are ready to test our freshly created chatroom. To do this ensure your messaging service is running. Now let's run two instances of the angular application on two different ports on two different terminals using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng serve

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When asked in the second terminal if you'd like to use a different port since Angular's default port 4200 is busy. Select yes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Once the Angular Live Development Server listens on the respective ports, you will see a prompt to enter your alias name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F6.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Enter your Alias name and click on submit. Both sessions will generate their own unique JWT Token and store it in the local storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F7.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Any message sent on one console will be actively receipted by the other thus creating a real-time online chatroom using Angular and Amplication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-assets.amplication.com%2Fblog%2Fcreating-a-chatroom-in-angular-using-amplication%2F8.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Thanks to our Community
&lt;/h1&gt;

&lt;p&gt;We hope you found this article on creating a chatroom in Angular using Amplication informative and inspiring. It is our pleasure to bring you valuable insights and practical guidance. We would like to extend our gratitude to &lt;a href="https://twitter.com/plastic96_" rel="noopener noreferrer"&gt;Akshita Dixit&lt;/a&gt; and &lt;a href="https://twitter.com/violinblackeye" rel="noopener noreferrer"&gt;Hamadaan Ali&lt;/a&gt;, dedicated members of the Amplication open source community for their invaluable contribution to this tutorial.&lt;/p&gt;

&lt;p&gt;We invite all developers and enthusiasts to join us in this collaborative journey. Your contributions can help shape the future of Amplication and empower developers worldwide. If you have any questions, encountered challenges, or simply want to connect with fellow developers, we encourage you to &lt;a href="https://amplication.com/discord" rel="noopener noreferrer"&gt;join the Amplication Discord server&lt;/a&gt;. There, you can engage in meaningful discussions, seek guidance, and share your experiences with the community.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>backend</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating Data Models for NodeJS Apps with Amplication's React Admin UI</title>
      <dc:creator>Akshita Dixit</dc:creator>
      <pubDate>Thu, 16 Feb 2023 07:41:19 +0000</pubDate>
      <link>https://dev.to/akshitadixit/creating-data-models-for-nodejs-apps-with-amplications-react-admin-ui-oho</link>
      <guid>https://dev.to/akshitadixit/creating-data-models-for-nodejs-apps-with-amplications-react-admin-ui-oho</guid>
      <description>&lt;p&gt;Data modeling is an essential aspect of building NodeJS applications. It is the process of creating a structured and organized representation of the data that will be used in your application. By properly modeling your data, you can ensure that it is organized, efficient, and easy to work with. In this blog post, we will be discussing the importance of data modeling in NodeJS applications and providing an overview of the different techniques and tools that can be used to model data in NodeJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Data Modeling?
&lt;/h2&gt;

&lt;p&gt;Data modeling in NodeJS typically involves creating a schema that defines the structure of the data and the relationships between different types of data. This schema is used to create tables or collections in a database, and it is used to validate, store, and retrieve data within the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrcoq558i5r4ezi6y1l2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrcoq558i5r4ezi6y1l2.png" alt="Image description" width="630" height="462"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Data_modeling" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two main types of data modeling in NodeJS: Relational data modeling and NoSQL data modeling.&lt;/p&gt;

&lt;p&gt;Relational data modeling involves creating a schema that defines the structure of the tables, fields, and relationships in a relational database such as MySQL or PostgreSQL. The schema is used to create tables, and it is used to define the relationships between different tables. This is a traditional way of data modeling and widely used in most of the applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://phoenixnap.com/kb/nosql-data-modeling" rel="noopener noreferrer"&gt;NoSQL data modeling&lt;/a&gt;, on the other hand, involves creating a schema for a NoSQL database such as MongoDB. NoSQL databases are document-based, and they do not have a fixed schema. Instead, the schema is defined by the structure of the documents. The data model in NoSQL databases is more flexible and allows for more scalability and performance.&lt;/p&gt;

&lt;p&gt;In addition to these, there are also &lt;a href="https://www.freecodecamp.org/news/what-is-an-orm-the-meaning-of-object-relational-mapping-database-tools/" rel="noopener noreferrer"&gt;Object-Relational Mapping&lt;/a&gt; (ORM) libraries such as Mongoose and Sequelize that can be used to model data in NodeJS. These libraries provide an abstraction layer between the application and the database, and they can be used to define the schema, validate data, and interact with the database.&lt;/p&gt;

&lt;p&gt;In summary, data modeling in NodeJS is an essential part of building NodeJS applications. It involves creating a structured and organized representation of the data that will be used in the application, and it is used to ensure that the data is organized, efficient, and easy to work with. Choosing the right technique and tools for data modeling is critical for ensuring data integrity, scalability, and performance of the application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up a New Project with React Admin
&lt;/h2&gt;

&lt;p&gt;Amplication's React Admin UI, built by &lt;a href="https://marmelab.com/react-admin/" rel="noopener noreferrer"&gt;Marmelab&lt;/a&gt; is an open source tool that can help developers create data models for their NodeJS apps quickly and easily. It provides a range of features for defining, validating, and querying data, making it easy to create intuitive and maintainable data structures. Therefore, in today’s tutorial we will be using it to create our data model. &lt;br&gt;
To get started with React Admin, you'll need to install it and any required dependencies. This can be done using npm (the Node Package Manager).&lt;br&gt;
First, create a new directory for your project and navigate to it in your terminal. Then, run the following command to install React Admin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you'll need to install any required dependencies. These may include packages such as Redux and GraphQL depending on your needs.&lt;br&gt;
Once all of the necessary dependencies have been installed, you can set up a new React Admin project by creating a new file called "App.js" and importing the necessary components from React Admin.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Admin, Resource } from 'react-admin';

const App = () =&amp;gt; (
    &amp;lt;Admin&amp;gt;
        // Add your resources here
    &amp;lt;/Admin&amp;gt;
);

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining Data Models with React Admin
&lt;/h2&gt;

&lt;p&gt;React Admin allows you to define a wide range of data types, including simple types like strings and numbers, as well as more complex types like relationships and nested objects.&lt;br&gt;
To create a new data model with React Admin, you can use the  component. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Admin, Resource } from 'react-admin';

const App = () =&amp;gt; (
    &amp;lt;Admin&amp;gt;
        &amp;lt;Resource name="users" /&amp;gt;
    &amp;lt;/Admin&amp;gt;
);

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new data model called "users", which you can then customize by adding fields and properties. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Admin, Resource } from 'react-admin';
import { TextField, EmailField } from 'react-admin';

const App = () =&amp;gt; (
    &amp;lt;Admin&amp;gt;
        &amp;lt;Resource name="users" list={UserList}&amp;gt;
            &amp;lt;TextField source="id" /&amp;gt;
            &amp;lt;TextField source="name" /&amp;gt;
            &amp;lt;EmailField source="email" /&amp;gt;
        &amp;lt;/Resource&amp;gt;
    &amp;lt;/Admin&amp;gt;
);

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a data model for users with three fields: "id", "name", and "email".&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Validation with React Admin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.safe.com/what-is/data-validation/" rel="noopener noreferrer"&gt;Data validation&lt;/a&gt; is the process of ensuring that data is entered in a consistent and correct format. This is important because it helps to prevent errors and ensure that data is accurate and reliable. In the context of a NodeJS application, data validation is especially important because it can help to prevent security vulnerabilities and improve the overall user experience.&lt;/p&gt;

&lt;p&gt;React Admin provides a number of built-in validation functions that can be used to validate data. These functions can be used to ensure that data meets certain criteria, such as being required, being a certain length, or matching a specific pattern.&lt;br&gt;
React Admin includes a number of built-in validation functions that you can use to validate your data. These functions can be imported from the react-admin package and applied to a field using the validate prop.&lt;br&gt;
For example, you can use the required() function to ensure that a particular field is not left blank:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { required } from 'react-admin';

&amp;lt;TextField source="name" validate={required()} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the minLength() and maxLength() functions to ensure that a field meets a certain length requirement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { minLength, maxLength } from 'react-admin';

&amp;lt;TextField source="password" validate={[minLength(8), maxLength(64)]} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to the built-in validation functions provided by React Admin, you can also create your own custom validation functions to fit your specific needs. This can be useful if you have requirements for data validation that are not covered by the built-in functions.&lt;br&gt;
To create a custom validation function, you can define a function that takes in a value and returns an error message if the value is invalid, or undefined if the value is valid.&lt;br&gt;
For example, you might want to create a validation function that checks that a particular field contains a valid email address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validateEmail = (email) =&amp;gt; {
    const regex = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
    if (!regex.test(email)) {
        return 'Invalid email address';
    }
    return undefined;
};

&amp;lt;TextField source="email" validate={validateEmail} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use your custom validation function just like any other validation function in React Admin. You can even combine multiple validation functions using the composeValidators() function, which takes in an array of validation functions and returns a single validation function that runs all of the validation functions in sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { composeValidators } from 'react-admin';

&amp;lt;TextField source="password" validate={composeValidators(required(), minLength(8), maxLength(64))} /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ensure that the "password" field is required, has a minimum length of 8 characters, and has a maximum length of 64 characters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying Data with React Admin
&lt;/h2&gt;

&lt;p&gt;Once you have defined your &lt;a href="https://amplication.com/#data-models" rel="noopener noreferrer"&gt;data models&lt;/a&gt; and set up validation, you'll want to query your data in order to display it or use it in your application. React Admin provides a number of different methods for querying data depending on your needs.&lt;/p&gt;

&lt;p&gt;One way to query data is to use React Admin's  component. This component allows you to fetch and display a list of records from your data model. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { List } from 'react-admin';
import { TextField } from 'react-admin';

const UserList = (props) =&amp;gt; (
    &amp;lt;List {...props}&amp;gt;
        &amp;lt;TextField source="id" /&amp;gt;
        &amp;lt;TextField source="name" /&amp;gt;
        &amp;lt;TextField source="email" /&amp;gt;
    &amp;lt;/List&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fetch a list of user records and display their "id", "name", and "email" fields.&lt;br&gt;
Another way to query data is to use React Admin's  component. This component allows you to create relationships between different data models and display related data. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ReferenceField } from 'react-admin';
import { TextField } from 'react-admin';

const PostList = (props) =&amp;gt; (
    &amp;lt;List {...props}&amp;gt;
        &amp;lt;TextField source="id" /&amp;gt;
        &amp;lt;TextField source="title" /&amp;gt;
        &amp;lt;ReferenceField label="Author" source="author_id" reference="users"&amp;gt;
            &amp;lt;TextField source="name" /&amp;gt;
        &amp;lt;/ReferenceField&amp;gt;
    &amp;lt;/List&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fetch a list of post records and display their "id", "title", and the "name" of the related user (as specified by the "author_id" field).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, data modeling is an essential aspect of building NodeJS applications. It is the process of creating a structured and organized representation of the data that will be used in your application. By properly modeling your data, you can ensure that it is organized, efficient, and easy to work with. &lt;/p&gt;

&lt;p&gt;We discussed the importance of data modeling in NodeJS applications and provided an overview of the different techniques and tools that can be used to model data in NodeJS, including Relational data modeling, NoSQL data modeling, and Object-Relational Mapping (ORM) libraries such as Mongoose and Sequelize. Additionally, we discussed Amplication’s React Admin UI, an open source tool that can help developers create data models for their NodeJS apps quickly and easily. &lt;/p&gt;

&lt;p&gt;By following the steps outlined in this blog post, you can create a data model that is intuitive, maintainable and reliable to ensure the scalability and performance of the application.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
