In the previous chapter, we tackled navigation using react-router. Now, we’ll be writing local states, sending HTTP requests using Axios, and installing ApexCharts to help us create an interactive chart in our app.
HTTP requests are essential parts of any web app communicating with a back-end server; meanwhile, a local state in React, as the name suggests, is handled locally or in isolation within a component. Any change in the state must be set or the state will be re-rendered using the setState function.
Axios and Fetch API are two of the most popular methods of how we can consume REST APIs. Axios is a promise-based HTTP client, while Fetch API is native to JavaScript and a built-in HTTP client in modern browsers.
In this chapter, we will do our best to stay organized and DRY (short for Don’t Repeat Yourself) using Axios for API requests. The DRY concept in programming is the process of abstraction to avoid repetition of code. Since, technically, we don’t have a back-end server, we will also create a fake Rest API using a JSON server.
ApexCharts is an open source charting library that we will be using to create modern-looking and interactive visualizations for our web page.
But before we start writing local states and sending HTTP requests, we will do some refactoring in our compiler options in TypeScript.
This is more for our personal preferences when using TypeScript in our application. Yes, we love the type safety features that TypeScript gives us that JavaScript cannot; however, we also do not want to lose the flexibility that JavaScript provides when developing our application. In short, we want the best of both worlds.
It is up to you whether you will opt out of the default strict type-checking options in TypeScript or not. There are two ways we can go about it.
Strict Type-Checking Options in TypeScript
As mentioned, there are two ways on how we personally use or set the type-checking options in TypeScript in our application.
tsconfig.json File
By default, the strict mode in the compilerOptions in tsconfig.json is set to true. It means all codes or files in the application will be validated or type-checked using the strict mode.
You can check out www.typescriptlang.org/tsconfig for more tsconfig reference.
Adding Fake Data Using json-server
The main benefit of using our own fake REST API is decoupling the front-end and back-end development work. If separate teams were working on the front end and the back end, the teams would only need to discuss and agree on JSON structures before they can work independently on their ends.
On the front end, using fake data can speed up the development process; no need to wait for the back end to finish building the real APIs.
And the setup? It lets us serve JSON from our file system through a local server.
Json-server is a fake Node.js server that gets scaffolded just by running the json-server. In npmjs.com, json-server is described as getting a “full fake REST API with zero coding in less than 30 seconds.” And yes, based on experience, it does its job quite well.
In the terminal, run $ npm run backend.
Now, let’s go back to our project; you’ll notice that a new file called db.json has been auto-generated for us in the root directory. Open it, and you’ll see the sample endpoints.
db.json Server Fake Data
Sending HTTP Requests Using Axios
Creating an instance of axios is extremely useful when building complex or large applications, especially when we need to integrate with multiple APIs. Implementing the default Axios instance can be cumbersome at times or would mean duplicating code throughout our app.
Building a full URL from a path
Assigning default headers
Caching
Global handling of network errors
Setting the Authorization header on requests automatically
Normalizing and managing error responses
Converting the request and response body
Refreshing access tokens and retrying requests
Setting a custom instance
axios.ts
We import axios from axios, and we’re using the create function of axios, which will create an instance of axios and put in our variable called api.
Within the instance api, there’s an option to pass an object of our configuration.
Currently, our default configuration is the localhost:5000/. The localhost:5000 as the baseURL is the default URL for any HTTP request within axios. Basically, it is the consistent or permanent part of the web address.
Creating a baseURL in one location offers us the ability to edit it easily as needed and be DRY in our app development. We don’t need to type repeatedly the baseURL of our API every time we create an HTTP request.
Okay, we’re done with that for now. We’ll keep on updating our axios file as we create more endpoints.
Shaping the Object
In TypeScript, we pass data through object types, whereas in JavaScript, we group and represent data through objects. Simply put, types let us know what an item looks like: string, number, boolean, array, function, etc.
Recall the two approaches to shaping our object in TypeScript: interface and type alias. They are more or less the same; it is just a matter of preference what you choose.
Creating the Shape or Model of Our Object
Making Requests with Axios
Before we proceed, let’s review a little what axios is. Axios is a promise-based HTTP client for the browser and Node.js. It allows us to intercept and cancel requests and provides a built-in feature called client-side protection against cross-site request forgery.
Sending Http Requests
The async-await just means that the axios function is promise-based.
Now, let’s test our api.get request.
Go to src/app/views/dashboard/dashboard-default-content.tsx.
We will do additional magic here, and for that, we’ll use the lifecycle Hook useEffect from React.
Import the named component from React.
Again, useEffect is a lifecycle Hook that runs after a React component is rendered. Inside this hook, we will invoke the getSalesAxios().
Calling the getSalesAxios in DashboardDefaultContent
Pass an empty array [ ] in the useEffect as a second argument to limit its run or to run the useEffect only once, after the first render.
Refresh our browser at localhost:3000/ and open the Chrome DevTools and make sure you are at the Network tab and XHR. We’re doing all these so-called baby-step processes on how I build an application.
Try to execute the low-level hanging fruit first, maybe write a lot of proof of concept, or check at the DevTools if everything is firing the way it should be.
Anyway, in your browser, click the Menu tab ➤ Dashboard.
Observe your Chrome DevTools; you should see the Response Method: Get and Status Code: 200 OK.
Click the Response tab to see the sale object data from the json-server.
So now we are confident that the UI is receiving data from the json-server. We sent the HTTP request and received JSON response from the json-server.
BUT since we might need to wrap the getSalesAxios in an async-await, we will invoke it outside of the useEffect.
Creating the fetchSales Function
We deconstructed the response to get just the data property and named it “data.”
Calling fetchSales in useEffect
Refresh the browser and make sure to open the Chrome DevTools again, and you should get a response from the json-server successfully.
Now that we know that we can retrieve data from the json-server, the next thing to do is create a local state using useState in the DashboardDefaultContent.
Add the component useState from React.
Creating a Local State
How do we update the value or data of the setSales?
Updating the Data of setSales
Okay, like I said before, I will often do this little proof of concept before I proceed.
Rendering the setSales
When you check the browser, you should see 2 because our sales array contains two objects. Go to Chrome DevTools ➤ Network to see the objects.
Now that we know that it’s working, the next plan is to improve the Dashboard Default Content.
In the components folder, let’s create a template for the web page. The template page will contain the set padding, spacing, and other styling to be applied to every page in our app.
The file path is src ➤ app ➤ components ➤ pages.tsx.
Let’s review some of the components here.
Forwarding Refs: This is adding a reference to the HTML. In reactjs.org, it says that it is a technique for automatically passing a ref through a component to one of its children, such as forwarding refs to DOM components or forwarding refs to higher-order components (HOCs).
Helmet: To add some tagging and allow us to build an SEO-friendly application.
Defining the Type Alias
We’re making our prop children of type ReactNode and prop title of type string, both nullable by appending ?. We’re also using HTMLProps of type HTMLDivElement.
Creating a Reusable Page Component
That’s done for now.
Let’s go back to our DashboardDefaultContent component and add more styling to the Dashboard.
Add the following styling component to the DashboardDefaultContent.
Adding useStyles and useTheme
After setting all that up, the next thing we need to do is install ApexCharts.
Installing ApexCharts
Importing Additional Material-UI Components
Updating the Page Component
So we’re reusing the Page component and giving it the title “Dashboard.” The Container, along with other style components, sets the look and feel of the DashboardDefaultContent page.
There’s still a long way to go, but we’re getting there to complete our Dashboard page.
Creating the Main Layout
Creating a New Main-Layout Component Page
Before we run again or check the browser if everything is still working, we will do a minor folder restructuring.
Using the MainLayout in the index.tsx of app
Adding Styling to the index.tsx of dashboard-layout
Adding the useStyles Component to the index.tsx of the dashboard-layout
Check the Dashboard, and you should see a better and responsive layout.
Using React Feather Icons
Last but not least, we’ll add a menu in the sidebar dashboard. We’ll use the React Feather icons.
Updating the dashboard-sidebar-navigation.tsx
Summary
We learned how to use local states, send HTTP requests while considering the DRY (Don’t Repeat Yourself) principle, and use the open source charting library called ApexCharts to create interactive visualizations for our app.
In the next chapter, we’ll go a little deeper into our app as we begin writing input forms using Formik and Yup validations on top of Material-UI’s data tables. Hopefully, we can bring all these components together and render them to the browser to see how everything works.