How to Connect Angular 8 With Mysql Database

The MySQL database has been a reliable workhorse for web applications for many years. It is the M in the LAMP stack, and powers a huge number of web servers across the world.

MySQL is also a relational database, with data stored in tables with strict data definitions. Rows in tables correspond to data entries and rows in one table can be referenced from another table through their index. Plenty of literature covers the fundamentals of SQL and best practices in designing relational databases for large applications.

Recently, MariaDB was created by some of the original developers of MySQL as an open-source alternative to MySQL, which is owned by Oracle. To keep all features available to the open-source community, MariaDB was created as a fork of MySQL. In fact, if you are using the default installation of MySQL on a modern Linux distribution, you are likely using MariaDB.

In this tutorial, I will show you how to develop an Angular application using MySQL. Instead of the old established LAMP stack, I will use a variant of the MEAN stack, where the M in MEAN refers to the MySQL database, with the Express.js framework to power the backend, and Angular.js for the client. The application will create a simple timeline in which the user can add and edit events, with a simple CRUD API.

I will assume that you have some familiarity with Node and the npm package manager and that both of these are installed on your system.

Table of Contents

  • Setting up MySQL
  • Set up a Simple CRUD Node Express Server
  • Run Your Express App and Connect to MySQL
  • Authentication With JWT
  • The Timeline Angular Client
  • Run Your Angular Client Application
  • Learn More About MySQL, Angular, and Node

Setting up MySQL

If you don't have installed MySQL on your system, follow the instructions on the MySQL website to do so. Depending on your operating system, you might be able to use the system's package manager to install the MySQL server.

Once you have installed MySQL you can create the database that you will use in this tutorial. Log into the database using the MySQL client using the login details of the database administrator.

The -p option indicates that you are required to supply a password when connecting to the MySQL server. You might not need this option, depending on how the database is set up on your system. You should now see the MySQL command line prompt.

Create a new database and switch into it by using the following command.

                          create              database              timeline              ;              use              timeline              ;                      

Next, create a user associated with this database. It is always a good idea to have separate users for each database on the system. The following commands will create the user and grant them all permissions on the timeline database.

                          create              user              'timeline'              @              'localhost'              identified              by              'password'              ;              grant              all              on              timeline              .              *              to              'timeline'              @              'localhost'              ;                      

In the first line, replace password with a more complex password. The rest of this tutorial assumes you used "password", so if you change it, please make sure and change it in all the code snippets below.

Now you are ready to create the events table in the new database by specifying the data schema.

                          create              table              events              (              id              INT              AUTO_INCREMENT              ,              owner              VARCHAR              (              255              )              NOT              NULL              ,              name              VARCHAR              (              255              )              NOT              NULL              ,              description              TEXT              ,              date              DATE              ,              PRIMARY              KEY              (              id              ),              INDEX              (              owner              ,              date              )              );                      

The table contains several columns called id, owner, name, description, and date. The id column acts as the primary key for accessing individual rows. Since you will need to look up entries by owner and date, I added a secondary index using these two fields to speed up the lookup. This completes the setup of the database and you can now exit the MySQL client by using the quit command.

Set up a Simple CRUD Node Express Server

To create the Express server, navigate into a directory of your choice and create a new folder called timeline-server. Open a terminal in this directory and initialize the Node project using npm.

Answer all the questions using the default answer and when asked about the entry point, set it to src/index.js. Next, install some libraries you will need.

            npm              install              --save-exact              express@4.17.1 cors@2.8.5 mysql@2.18.1                      

Next, use your favorite editor and create a file src/index.js and paste the following code into it.

                          const              express              =              require              (              '              express              '              );              const              cors              =              require              (              '              cors              '              );              const              bodyParser              =              require              (              '              body-parser              '              );              const              mysql              =              require              (              '              mysql              '              );              const              events              =              require              (              '              ./events              '              );              const              connection              =              mysql              .              createConnection              ({              host              :              '              localhost              '              ,              user              :              '              timeline              '              ,              password              :              '              password              '              ,              database              :              '              timeline              '              });              connection              .              connect              ();              const              port              =              process              .              env              .              PORT              ||              8080              ;              const              app              =              express              ()              .              use              (              cors              ())              .              use              (              bodyParser              .              json              ())              .              use              (              events              (              connection              ));              app              .              listen              (              port              ,              ()              =>              {              console              .              log              (              `Express server listening on port                            ${              port              }              `              );              });                      

At the top of the file, you can see several imports. express contains the Express framework for creating REST APIs, cors is a middleware responsible for allowing cross-origin requests, and body-parser makes sure that the bodies of the incoming requests are read and attached to the request object.

The mysql object allows us to connect to your MySQL database and is seen in the code immediately below the require statements. In the options to createConnection, you will need to replace password with the password that you have stored in your MySQL server above. In the bottom part of src/index.js, the Express server is configured with the middleware and the events router and then started.

The last require statement imports the events router. To create the router, create a new file called src/events.js and paste the following code.

                          const              express              =              require              (              '              express              '              );              function              createRouter              (              db              )              {              const              router              =              express              .              Router              ();              const              owner              =              ''              ;              // the routes are defined here              return              router              ;              }              module              .              exports              =              createRouter              ;                      

This piece of code defines a function that takes the database connection as an argument and creates a router. I deliberately left the main part of the function blank. Soon, you will define the individual routes of the REST API in this block. I also defined an empty string called owner to use as a placeholder for the owner column in the database. In the next section, I will show you how to obtain the user's email address and use this to identify the owner.

The first route will insert new events into the database. Paste the following into the body of the createRouter() function.

                          router              .              post              (              '              /event              '              ,              (              req              ,              res              ,              next              )              =>              {              db              .              query              (              '              INSERT INTO events (owner, name, description, date) VALUES (?,?,?,?)              '              ,              [              owner              ,              req              .              body              .              name              ,              req              .              body              .              description              ,              new              Date              (              req              .              body              .              date              )],              (              error              )              =>              {              if              (              error              )              {              console              .              error              (              error              );              res              .              status              (              500              ).              json              ({              status              :              '              error              '              });              }              else              {              res              .              status              (              200              ).              json              ({              status              :              '              ok              '              });              }              }              );              });                      

By using router.post this route will only activate when the server receives an HTTP POST request. The data posted in the request can be obtained through the req.body object. Using the SQL INSERT statement, this code adds a new row into the events table.

To list the events of a single owner, the following route links an HTTP GET request to a MySQL SELECT statement. You can paste this code into the body of the createRouter() function right after the previous route.

                          router              .              get              (              '              /event              '              ,              function              (              req              ,              res              ,              next              )              {              db              .              query              (              '              SELECT id, name, description, date FROM events WHERE owner=? ORDER BY date LIMIT 10 OFFSET ?              '              ,              [              owner              ,              10              *              (              req              .              params              .              page              ||              0              )],              (              error              ,              results              )              =>              {              if              (              error              )              {              console              .              log              (              error              );              res              .              status              (              500              ).              json              ({              status              :              '              error              '              });              }              else              {              res              .              status              (              200              ).              json              (              results              );              }              }              );              });                      

You can also modify existing entries in the database with a PUT route, which links an HTTP PUT request to a MySQL UPDATE statement.

                          router              .              put              (              '              /event/:id              '              ,              function              (              req              ,              res              ,              next              )              {              db              .              query              (              '              UPDATE events SET name=?, description=?, date=? WHERE id=? AND owner=?              '              ,              [              req              .              body              .              name              ,              req              .              body              .              description              ,              new              Date              (              req              .              body              .              date              ),              req              .              params              .              id              ,              owner              ],              (              error              )              =>              {              if              (              error              )              {              res              .              status              (              500              ).              json              ({              status              :              '              error              '              });              }              else              {              res              .              status              (              200              ).              json              ({              status              :              '              ok              '              });              }              }              );              });                      

The code obtains the id as a route parameter, from the req.params object.

Finally, you might want to delete an existing event. Do this through an HTTP DELETE request that issues a MySQL DELETE statement.

                          router              .              delete              (              '              /event/:id              '              ,              function              (              req              ,              res              ,              next              )              {              db              .              query              (              '              DELETE FROM events WHERE id=? AND owner=?              '              ,              [              req              .              params              .              id              ,              owner              ],              (              error              )              =>              {              if              (              error              )              {              res              .              status              (              500              ).              json              ({              status              :              '              error              '              });              }              else              {              res              .              status              (              200              ).              json              ({              status              :              '              ok              '              });              }              }              );              });                      

Run Your Express App and Connect to MySQL

The code above implements a fully functioning server. You can run this server by opening the terminal in the project directory and running the following command.

You might see the following error when you run this command:

            Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client                      

To fix this, log into MySQL and execute the following SQL (where password is the value you used for your password):

                          ALTER              USER              'timeline'              @              'localhost'              IDENTIFIED              WITH              mysql_native_password              BY              'password'              ;                      

Authentication With JWT

In this section, I will show you how to use JWT and Okta to authenticate users to your application. User authentication is an important part of any web app, but developers often underestimate the effort required to safely implement and maintain secure authentication. With Okta, you can offload all the complexity and security considerations to an external provider.

Before you begin, you'll need a free Okta developer account. Install the Okta CLI and run okta register to sign up for a new account. If you already have an account, run okta login. Then, run okta apps create. Select the default app name, or change it as you see fit. Choose Single-Page App and press Enter.

Use http://localhost:4200/callback for the Redirect URI and accept the default Logout Redirect URI of http://localhost:4200.

What does the Okta CLI do?

The Okta CLI will create an OIDC Single-Page App in your Okta Org. It will add the redirect URIs you specified and grant access to the Everyone group. It will also add a trusted origin for http://localhost:4200. You will see output like the following when it's finished:

              Okta application configuration: Issuer:    https://dev-133337.okta.com/oauth2/default Client ID: 0oab8eb55Kb9jdMIr5d6                          

NOTE: You can also use the Okta Admin Console to create your app. See Create an Angular App for more information.

To use Okta authentication in your server app, you need to install some additional libraries. In the terminal run the following command:

            npm              install              --save-exact              express-bearer-token@2.4.0 @okta/jwt-verifier@2.1.0                      

Next, create a new file src/auth.js and paste the following code.

                          const              OktaJwtVerifier              =              require              (              '              @okta/jwt-verifier              '              );              const              oktaJwtVerifier              =              new              OktaJwtVerifier              ({              clientId              :              '              {yourClientId}              '              ,              issuer              :              '                                                https://{yourOktaDomain}                /oauth2/default              '              });              async              function              oktaAuth              (              req              ,              res              ,              next              )              {              try              {              const              token              =              req              .              token              ;              if              (              !              token              )              {              return              res              .              status              (              401              ).              send              (              '              Not Authorized              '              );              }              const              jwt              =              await              oktaJwtVerifier              .              verifyAccessToken              (              token              ,              [              '              api://default              '              ]);              req              .              user              =              {              uid              :              jwt              .              claims              .              uid              ,              email              :              jwt              .              claims              .              sub              };              next              ();              }              catch              (              err              )              {              console              .              log              (              '              AUTH ERROR:                            '              ,              err              );              return              res              .              status              (              401              ).              send              (              err              .              message              );              }              }              module              .              exports              =              oktaAuth              ;                      

This module defines an Express middleware that reads a token from the request and verifies it using the Okta JWT Verifier. In the code above {yourClientId} is the client ID you obtained from the Okta application settings and {yourOktaDomain} is your Okta domain. When the user authenticates successfully, a user object containing the user ID and email will be added to the request.

Open src/index.js again and add the following require statements to the top of the file.

                          const              bearerToken              =              require              (              '              express-bearer-token              '              );              const              oktaAuth              =              require              (              '              ./auth              '              );                      

Now modify the Express application configuration to include the bearerToken and oktaAuth middlewares.

                          const              app              =              express              ()              .              use              (              cors              ())              .              use              (              bodyParser              .              json              ())              .              use              (              bearerToken              ())              .              use              (              oktaAuth              )              .              use              (              events              (              connection              ));                      

Finally, modify the event route to make use of the user email. In src/events.js, remove the line const owner = ''; and add const owner = req.user.email; to the first line in each router block:

                          router              .              post              (              '              /event              '              ,              (              req              ,              res              ,              next              )              =>              {              const              owner              =              req              .              user              .              email              ;              // db.query() code              });              router              .              get              (              '              /event              '              ,              function              (              req              ,              res              ,              next              )              {              const              owner              =              req              .              user              .              email              ;              // db.query() code              });              router              .              put              (              '              /event/:id              '              ,              function              (              req              ,              res              ,              next              )              {              const              owner              =              req              .              user              .              email              ;              // db.query() code              });              router              .              delete              (              '              /event/:id              '              ,              function              (              req              ,              res              ,              next              )              {              const              owner              =              req              .              user              .              email              ;              // db.query() code              });                      

These changes secure your server application. It also stores events for users separately and each user will only see their own events.

The Timeline Angular Client

Now it's time to implement the client application, based on Angular 8 with the ngx-bootstrap library for responsive layout and standard components. You will also use a free icon set called Line Awesome, a variant of the well known Font Awesome that replaces the standard icon designs with some stylish line icons. You will also use the ngx-timeline library to make it easy to create beautiful vertical timelines.

To start, you will need to install the latest version of the Angular CLI tool. In a terminal, type the following command.

            npm              install              -g              @angular/cli@8                      

Depending on your system, you might have to run this command using sudo to allow modification of system resources. Next, navigate into a directory of your choice and create a new Angular application.

You will be asked a number of questions about your applications. Make sure that you add the Angular routing module.

            ? Would you like to add Angular routing?              (y/N)              Y                      

When asked which stylesheet format to use, choose the default CSS option. Now change into the new folder timeline-client and install some additional packages. Add Bootstrap with the ng add command.

            ng add ngx-bootstrap@5.1.0                      

To add the timeline library and Okta's Angular SDK, run the following command:

            npm              install              --save-exact              ngx-timeline@5.0.0 @okta/okta-angular@3.0.1                      

Now start your IDE and open up the file src/index.html. Here, add some external CSS files inside the <head> tags to add styles for Bootstrap and Line Awesome:

                          <link              href=              "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"              rel=              "stylesheet"              >              <link              rel=              "stylesheet"              href=              "https://maxcdn.icons8.com/fonts/line-awesome/1.1/css/line-awesome-font-awesome.min.css"              >                      

Open src/app/app.component.ts and replace the contents with the following code.

                          import              {              Component              ,              OnInit              }              from              '              @angular/core              '              ;              import              {              OktaAuthService              }              from              '              @okta/okta-angular              '              ;              @              Component              ({              selector              :              '              app-root              '              ,              templateUrl              :              '              ./app.component.html              '              ,              styleUrls              :              [              '              ./app.component.css              '              ]              })              export              class              AppComponent              implements              OnInit              {              title              =              '              timeline-client              '              ;              isAuthenticated              :              boolean              ;              constructor              (              public              oktaAuth              :              OktaAuthService              )              {              // subscribe to authentication state changes              this              .              oktaAuth              .              $authenticationState              .              subscribe              (              (              isAuthenticated              :              boolean              )              =>              this              .              isAuthenticated              =              isAuthenticated              );              }              async              ngOnInit              ()              {              // get authentication state for immediate use              this              .              isAuthenticated              =              await              this              .              oktaAuth              .              isAuthenticated              ();              }              async              login              ()              {              await              this              .              oktaAuth              .              signInWithRedirect              ();              }              async              logout              ()              {              await              this              .              oktaAuth              .              signOut              ();              }              }                      

The AppComponent handles the authentication through Okta. OktaAuthService.isAuthenticated() initializes the isAuthenticated field of the component. The field is kept up to date by subscribing to the OktaAuthService.$authenticationState observable. OktaAuthService.signInWithRedirect() will trigger a browser redirect to the Okta login page and OktaAuthService.signOut() will log out the user.

Now open the template of the application component src/app/app.component.html and paste in the following HTML.

                          <nav              class=              "navbar navbar-expand navbar-light bg-light"              >              <a              class=              "navbar-brand"              [routerLink]=              "['']"              >              <i              class=              "fa fa-clock-o"              ></i>              </a>              <ul              class=              "navbar-nav mr-auto"              >              <li              class=              "nav-item"              >              <a              class=              "nav-link"              [routerLink]=              "['']"              >              Home              </a>              </li>              <li              class=              "nav-item"              >              <a              class=              "nav-link"              [routerLink]=              "['timeline']"              >              Timeline              </a>              </li>              </ul>              <span>              <button              class=              "btn btn-primary"              *ngIf=              "!isAuthenticated"              (click)=              "login()"              >              Login              </button>              <button              class=              "btn btn-primary"              *ngIf=              "isAuthenticated"              (click)=              "logout()"              >              Logout              </button>              </span>              </nav>              <router-outlet></router-outlet>                      

The bootstrap navigation bar contains a menu with links to the home page and a timeline route. It also contains a login button and a logout button that appear depending on the authentication state.

In the next step, you need to import the component modules into src/app/app.module.ts. It looks like this.

                          import              {              BrowserModule              }              from              '              @angular/platform-browser              '              ;              import              {              HttpClientModule              }              from              '              @angular/common/http              '              ;              import              {              NgModule              }              from              '              @angular/core              '              ;              import              {              BsDatepickerModule              }              from              '              ngx-bootstrap/datepicker              '              ;              import              {              NgxTimelineModule              }              from              '              ngx-timeline              '              ;              import              {              FormsModule              ,              ReactiveFormsModule              }              from              '              @angular/forms              '              ;              import              {              AppRoutingModule              }              from              '              ./app-routing.module              '              ;              import              {              AppComponent              }              from              '              ./app.component              '              ;              import              {              BrowserAnimationsModule              }              from              '              @angular/platform-browser/animations              '              ;              import              {              ModalModule              }              from              '              ngx-bootstrap/modal              '              ;              import              {              HomeComponent              }              from              '              ./home/home.component              '              ;              import              {              TimelineComponent              }              from              '              ./timeline/timeline.component              '              ;              import              {              OKTA_CONFIG              ,              OktaAuthModule              }              from              '              @okta/okta-angular              '              ;              const              oktaConfig              =              {              issuer              :              '                                                https://{yourOktaDomain}                /oauth2/default              '              ,              clientId              :              '              {clientId}              '              ,              redirectUri              :              window              .              location              .              origin              +              '              /callback              '              };              @              NgModule              ({              declarations              :              [              AppComponent              ,              HomeComponent              ,              TimelineComponent              ],              imports              :              [              BrowserModule              ,              HttpClientModule              ,              AppRoutingModule              ,              BrowserAnimationsModule              ,              FormsModule              ,              ReactiveFormsModule              ,              BsDatepickerModule              .              forRoot              (),              NgxTimelineModule              ,              ModalModule              .              forRoot              (),              OktaAuthModule              ],              providers              :              [{              provide              :              OKTA_CONFIG              ,              useValue              :              oktaConfig              }],              bootstrap              :              [              AppComponent              ]              })              export              class              AppModule              {              }                      

Replace{yourClientId} with your client ID and {yourOktaDomain} with your Okta domain. If you closed your terminal window, you can run okta apps to see your apps and okta apps config --app=<clientId> to get your app's info.

Next, create two components for the home page and the timeline page, as well as a service to connect to the server.

            ng generate component home ng generate component timeline ng generate service server                      

The home page will simply contain a heading and no other functionality. Open src/app/home/home.component.html and replace the contents with the following.

                          <div              class=              "container"              >              <div              class=              "row"              >              <div              class=              "col-sm"              >              <h1>Angular MySQL Timeline</h1>              </div>              </div>              </div>                      

Now open src/app/home/home.component.css and add the following styles.

                          h1              {              margin-top              :              50px              ;              text-align              :              center              ;              }                      

Before you implement the timeline component, let's take a look at the ServerService first. Open src/app/server.service.ts and replace the contents with the following code.

                          import              {              Injectable              }              from              '              @angular/core              '              ;              import              {              HttpClient              }              from              '              @angular/common/http              '              ;              import              {              OktaAuthService              }              from              '              @okta/okta-angular              '              ;              import              {              environment              }              from              '              ../environments/environment              '              ;              @              Injectable              ({              providedIn              :              '              root              '              })              export              class              ServerService              {              constructor              (              private              http              :              HttpClient              ,              public              oktaAuth              :              OktaAuthService              )              {              }              private              async              request              (              method              :              string              ,              url              :              string              ,              data              ?:              any              )              {              const              token              =              await              this              .              oktaAuth              .              getAccessToken              ();              const              result              =              this              .              http              .              request              (              method              ,              url              ,              {              body              :              data              ,              responseType              :              '              json              '              ,              observe              :              '              body              '              ,              headers              :              {              Authorization              :              `Bearer                            ${              token              }              `              }              });              return              new              Promise              ((              resolve              ,              reject              )              =>              {              result              .              subscribe              (              resolve              ,              reject              );              });              }              getEvents              ()              {              return              this              .              request              (              '              GET              '              ,              `              ${              environment              .              serverUrl              }              /event`              );              }              createEvent              (              event              )              {              return              this              .              request              (              '              POST              '              ,              `              ${              environment              .              serverUrl              }              /event`              ,              event              );              }              updateEvent              (              event              )              {              return              this              .              request              (              '              PUT              '              ,              `              ${              environment              .              serverUrl              }              /event/              ${              event              .              id              }              `              ,              event              );              }              deleteEvent              (              event              )              {              return              this              .              request              (              '              DELETE              '              ,              `              ${              environment              .              serverUrl              }              /event/              ${              event              .              id              }              `              );              }              }                      

The main logic of this component resides in the request method, which sends a request to the server. To identify the user to the server, the request header contains a bearer token obtained from OktaAuthService. The method returns a Promise that resolves once a response from the server has been obtained.

The remainder of the ServerService uses the request method to call the server routes. The server URL is provided through the environment object, which you need to define in src/environments/environment.ts.

                          export              const              environment              =              {              production              :              false              ,              serverUrl              :              '              http://localhost:8080              '              };                      

The comments in src/environments/environment.ts provide useful hints about how to use environments in Angular.

Now you are ready to implement the timeline component. Open src/app/timeline/timeline.component.html and edit the contents to match the code below.

                          <div              class=              "container page-content"              >              <div              class=              "row"              >              <div              class=              "col-sm-12 col-md"              >              <ngx-timeline              [events]=              "events"              >              <ng-template              let-event              let-index=              "rowIndex"              timelineBody              >              <div>{{event.body}}</div>              <div              class=              "button-row"              >              <button              type=              "button"              class=              "btn btn-primary"              (click)=              "editEvent(index, eventmodal)"              ><i              class=              "fa fa-edit"              ></i></button>              <button              type=              "button"              class=              "btn btn-danger"              (click)=              "deleteEvent(index)"              ><i              class=              "fa fa-trash"              ></i></button>              </div>              </ng-template>              </ngx-timeline>              </div>              <div              class=              "col-md-2"              >              <button              type=              "button"              class=              "btn btn-primary"              (click)=              "addEvent(eventmodal)"              ><i              class=              "fa fa-plus"              ></i>              Add</button>              </div>              </div>              </div>                      

This template uses the ngx-timeline component to display an array of events in a vertical timeline, with buttons for adding and editing events. Some of these actions will open up a modal window. ngx-bootstrap allows you to simply create a modal window from an ng-template component. Paste the following code into the bottom of the file.

                          <ng-template              #eventmodal              >              <div              class=              "modal-header"              >              <h4              class=              "modal-title pull-left"              >Event</h4>              <button              type=              "button"              class=              "close pull-right"              aria-label=              "Close"              (click)=              "modalRef.hide()"              >              <span              aria-hidden=              "true"              >              &times;              </span>              </button>              </div>              <div              class=              "modal-body"              >              <form              [formGroup]=              "form"              (ngSubmit)=              "onSubmit()"              >              <div              class=              "form-group full-width-input"              >              <label>Name</label>              <input              class=              "form-control"              placeholder=              "Event Name"              formControlName=              "name"              required              >              </div>              <div              class=              "form-group full-width-input"              >              <label>Description</label>              <input              class=              "form-control"              formControlName=              "description"              >              </div>              <div              class=              "form-group full-width-input"              >              <label>Date</label>              <input              class=              "form-control"              formControlName=              "date"              bsDatepicker              >              </div>              <div              class=              "button-row"              >              <button              type=              "button"              class=              "btn btn-primary"              (click)=              "modalCallback()"              >Submit</button>              <button              type=              "button"              class=              "btn btn-light"              (click)=              "onCancel()"              >Cancel</button>              </div>              </form>              </div>              </ng-template>                      

Only a small amount of styling in src/app/timeline/timeline.component.css rounds off the design.

                          .page-content              {              margin-top              :              2rem              ;              }              .button-row              {              display              :              flex              ;              justify-content              :              space-between              ;              margin-top              :              1rem              ;              }                      

The src/app/timeline/timeline.component.ts file contains the bulk of the application logic.

                          import              {              Component              ,              OnInit              }              from              '              @angular/core              '              ;              import              {              BsModalService              ,              BsModalRef              }              from              '              ngx-bootstrap/modal              '              ;              import              {              FormGroup              ,              FormBuilder              ,              Validators              }              from              '              @angular/forms              '              ;              import              {              ServerService              }              from              '              ../server.service              '              ;              @              Component              ({              selector              :              '              app-timeline              '              ,              templateUrl              :              '              ./timeline.component.html              '              ,              styleUrls              :              [              '              ./timeline.component.css              '              ]              })              export              class              TimelineComponent              implements              OnInit              {              form              :              FormGroup              ;              modalRef              :              BsModalRef              ;              events              :              any              []              =              [];              currentEvent              :              any              =              {              id              :              null              ,              name              :              ''              ,              description              :              ''              ,              date              :              new              Date              ()};              modalCallback              :              ()              =>              void              ;              constructor              (              private              fb              :              FormBuilder              ,              private              modalService              :              BsModalService              ,              private              server              :              ServerService              )              {              }              ngOnInit              ()              {              this              .              form              =              this              .              fb              .              group              ({              name              :              [              this              .              currentEvent              .              name              ,              Validators              .              required              ],              description              :              this              .              currentEvent              .              description              ,              date              :              [              this              .              currentEvent              .              date              ,              Validators              .              required              ],              });              this              .              getEvents              ();              }              private              updateForm              ()              {              this              .              form              .              setValue              ({              name              :              this              .              currentEvent              .              name              ,              description              :              this              .              currentEvent              .              description              ,              date              :              new              Date              (              this              .              currentEvent              .              date              )              });              }              private              getEvents              ()              {              this              .              server              .              getEvents              ().              then              ((              response              :              any              )              =>              {              console              .              log              (              '              Response              '              ,              response              );              this              .              events              =              response              .              map              ((              ev              )              =>              {              ev              .              body              =              ev              .              description              ;              ev              .              header              =              ev              .              name              ;              ev              .              icon              =              '              fa-clock-o              '              ;              return              ev              ;              });              });              }              addEvent              (              template              )              {              this              .              currentEvent              =              {              id              :              null              ,              name              :              ''              ,              description              :              ''              ,              date              :              new              Date              ()};              this              .              updateForm              ();              this              .              modalCallback              =              this              .              createEvent              .              bind              (              this              );              this              .              modalRef              =              this              .              modalService              .              show              (              template              );              }              createEvent              ()              {              const              newEvent              =              {              name              :              this              .              form              .              get              (              '              name              '              ).              value              ,              description              :              this              .              form              .              get              (              '              description              '              ).              value              ,              date              :              this              .              form              .              get              (              '              date              '              ).              value              ,              };              this              .              modalRef              .              hide              ();              this              .              server              .              createEvent              (              newEvent              ).              then              (()              =>              {              this              .              getEvents              ();              });              }              editEvent              (              index              ,              template              )              {              this              .              currentEvent              =              this              .              events              [              index              ];              this              .              updateForm              ();              this              .              modalCallback              =              this              .              updateEvent              .              bind              (              this              );              this              .              modalRef              =              this              .              modalService              .              show              (              template              );              }              updateEvent              ()              {              const              eventData              =              {              id              :              this              .              currentEvent              .              id              ,              name              :              this              .              form              .              get              (              '              name              '              ).              value              ,              description              :              this              .              form              .              get              (              '              description              '              ).              value              ,              date              :              this              .              form              .              get              (              '              date              '              ).              value              ,              };              this              .              modalRef              .              hide              ();              this              .              server              .              updateEvent              (              eventData              ).              then              (()              =>              {              this              .              getEvents              ();              });              }              deleteEvent              (              index              )              {              this              .              server              .              deleteEvent              (              this              .              events              [              index              ]).              then              (()              =>              {              this              .              getEvents              ();              });              }              onCancel              ()              {              this              .              modalRef              .              hide              ();              }              }                      

I will not go into every detail of this code. The methods addEvent(), editEvent(), and deleteEvent() are the event handlers for the respective HTML buttons. addEvent() and editEvent() open the modal window and set either createEvent() or updateEvent() as a callback function when the user submits data. These use the ServerService to complete the request.

Finally, link the components to the routes. Open src/app/app-routing.module.ts and add the following import statements to the top of the file.

                          import              {              HomeComponent              }              from              '              ./home/home.component              '              ;              import              {              TimelineComponent              }              from              '              ./timeline/timeline.component              '              ;              import              {              OktaCallbackComponent              ,              OktaAuthGuard              }              from              '              @okta/okta-angular              '              ;                      

Next, replace the routes array with the following.

                          const              routes              :              Routes              =              [              {              path              :              ''              ,              component              :              HomeComponent              },              {              path              :              '              timeline              '              ,              component              :              TimelineComponent              ,              canActivate              :              [              OktaAuthGuard              ]              },              {              path              :              '              callback              '              ,              component              :              OktaCallbackComponent              }              ];                      

The first entry sets the base route and links it to the HomeComponent. The second entry links the timeline route to the TimelineComponent and prevents unauthorized access to the route with OktaAuthGuard. When a user authenticates via the Okta service, they will be redirected to the /callback route.

Run Your Angular Client Application

This completes the implementation of the client. You can start the client from the terminal by running this command.

Make sure that you have also started the server as described in the previous section. Open a browser to http://localhost:4200. Log in, click on Timeline in the top menu, and add events to your heart's content.

I added some of my favorite historical events. You can see how this looks in the screenshot below.

A timeline application using Angular and MySQL

Learn More About MySQL, Angular, and Node

In this tutorial, I have shown you how to implement a web application with Angular and MySQL using a server based on Express. Using the ngx-timeline library you created beautiful timelines. When written from scratch, authentication requires solid up-to-date knowledge about security issues. Using Okta authentication and helper libraries lets you implement authentication in just a few lines.

You can find the code created in this tutorial on GitHub at okta-angular-mysql-timeline-example.

If you want to learn more about Angular, MySQL, and authentication, check out the links below.

  • Use the Okta CLI to Quickly Build Secure Angular Apps
  • Build a Basic CRUD App with Angular and Node
  • Build Secure Login for Your Angular App
  • Build a Node.js API with TypeScript
  • Modern Token Authentication in Node with Express

If you'd like to be notified when we publish new posts like this one, please follow @oktadev on Twitter. We also publish videos to our YouTube channel.

How to Connect Angular 8 With Mysql Database

Source: https://developer.okta.com/blog/2019/08/16/angular-mysql-express

0 Response to "How to Connect Angular 8 With Mysql Database"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel