{"id":2275,"date":"2022-01-25T18:32:04","date_gmt":"2022-01-25T18:32:04","guid":{"rendered":"https:\/\/lvboard.infostore.in.ua\/?p=2275"},"modified":"2022-01-25T18:32:04","modified_gmt":"2022-01-25T18:32:04","slug":"building-a-fullstack-road-trip-mapper-app-using-the-absolute-power-of-mern-stack","status":"publish","type":"post","link":"https:\/\/lvboard.infostore.in.ua\/?p=2275","title":{"rendered":"Building a Fullstack Road trip mapper app using the absolute power of MERN stack"},"content":{"rendered":"\n<p>This article concentrates on the most critical tasks and concepts for better understanding and building MERN stack applications from the ground up. It&#8217;s for folks who are serious about learning about the MERN stack and want to concentrate on the essentials. <\/p>\n\n\n\n<!--more-->\n\n\n\n<p>We&#8217;ll build a full-stack road trip mapper application where users can pin and map locations and view the sites pinned by other users, all using the MERN stack and leveraging the power of the Mapbox API. This blog session will teach you the fundamentals of MERN stack technology as well as advanced concepts and operations.<\/p>\n\n\n\n<p><strong><em>Here&#8217;s a quick preview of our application&#8217;s final version:<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--8zGgghdw--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933630247-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--8zGgghdw--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933630247-image-resized.png\" alt=\"Demo\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--1DLhm83v--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933711894-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--1DLhm83v--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933711894-image-resized.png\" alt=\"Demo\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--YKzZLub1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933834026-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--YKzZLub1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933834026-image-resized.png\" alt=\"Demo\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--U2bRJcFe--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637934178664-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--U2bRJcFe--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637934178664-image-resized.png\" alt=\"Demo\"\/><\/a><\/figure>\n\n\n\n<p>There is a separate article where you may learn about the MERN stack in very great detail.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/aviyel.com\/post\/1278\n<\/div><\/figure>\n\n\n\n<p><strong><em>Setting up the folder structure<\/em><\/strong><\/p>\n\n\n\n<p>Create two folders inside your project directory called client and server, then open them in Visual Studio Code or any other code editor of your choice.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--qVVuvow1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637928697125-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--qVVuvow1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637928697125-image-resized.png\" alt=\"Making Directory\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--3BupR6RD--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637740494285-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--3BupR6RD--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637740494285-image.png\" alt=\"Folder structure\"\/><\/a><\/figure>\n\n\n\n<p>Now, we&#8217;ll create a MongoDB database, a Node and Express server, a database schema to represent our project case study application, and API routes to create, read, update, and delete data and information from the database using npm and the appropriate packages. So, open a command prompt, navigate to your server&#8217;s directory, and then run the code below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm init -yes\n<\/code><\/pre>\n\n\n\n<p><strong><em>Configuring package.json file<\/em><\/strong><\/p>\n\n\n\n<p>Execute the following commands in the terminal to install the dependencies.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install cors dotenv express express-rate-limit mongoose nodemon body-parser helmet morgan rate-limit-mongo\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--OjOXTvcW--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637929452248-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--OjOXTvcW--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637929452248-image-resized.png\" alt=\"Dependencies\"\/><\/a><\/figure>\n\n\n\n<ul><li>Dotenv: Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env<\/li><li>cors: This module allows to relax the security applied to an API<\/li><li>express: Fast, unopinionated, minimalist web framework for node.<\/li><li>express-rate-limit: Basic IP rate-limiting middleware for Express. It is used to limit repeated requests to public APIs and\/or endpoints such as password reset.<\/li><li>mongoose: It is an Object Data Modeling library for MongoDB and Node. js<\/li><li>nodemon: This module helps to develop node.js based applications by automatically restarting the application when file changes in the directory are detected.<\/li><li>body-parser: Node.js body parsing middleware.<\/li><li>helmet: Helmet.js fills in the gap between Node.js and Express.js by securing HTTP headers that are returned by Express applications.<\/li><li>morgan : HTTP request logger middleware for node.js<\/li><li>rate-limit-mongo : MongoDB store for the express-rate-limit middleware.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--ONfBH_d7--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637935056359-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--ONfBH_d7--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637935056359-image-resized.png\" alt=\"Dependencies Installation\"\/><\/a><\/figure>\n\n\n\n<p>The &#8220;package.json&#8221; file should look like this after the dependencies have been installed.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_p2ZJEM1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637930533828-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_p2ZJEM1--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637930533828-image-resized.png\" alt=\"Package JSON\"\/><\/a><\/figure>\n\n\n\n<p>And also, remember to update the scripts as well.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--parquAzH--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637930580698-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--parquAzH--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637930580698-image-resized.png\" alt=\"Scripts\"\/><\/a><\/figure>\n\n\n\n<p>Now go to your server directory, create a src folder, and an index.js file there.<\/p>\n\n\n\n<p>Setting up index.js<\/p>\n\n\n\n<ul><li>Import express module.<\/li><li>Import and configure dotenv module<\/li><li>Import helmet module.<\/li><li>Import morgan module.<\/li><li>Import CORS module<\/li><li>Use express() to initialize our app.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/index.js\nconst express = require('express');\n\/\/ NOTE morgan is a logger\nconst morgan = require('morgan');\nconst helmet = require('helmet');\nconst cors = require('cors');\nconst mongoose = require('mongoose');\n\nrequire('dotenv').config();\n\n\/\/ app config\nconst app = express();\n<\/code><\/pre>\n\n\n\n<p>We may now utilize all of the other methods on that app instance. Let&#8217;s start with the fundamentals and very basic setups. Don&#8217;t forget to set up the port and cors, too.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require('express');\n\/\/ NOTE morgan is a logger\nconst morgan = require('morgan');\nconst helmet = require('helmet');\nconst cors = require('cors');\nconst mongoose = require('mongoose');\n\nrequire('dotenv').config();\n\nconst app = express();\n\nconst port = process.env.PORT || 4000;\n\napp.use(morgan('common'));\napp.use(helmet());\napp.use(cors({\n  origin: process.env.CORS_ORIGIN,\n}));\n\napp.use(express.json());\n\napp.get('\/', (req, res) =&gt; {\n  res.json({\n    message: 'Hello There',\n  });\n});\n<\/code><\/pre>\n\n\n\n<p>Now it&#8217;s time to connect our server application to a real database. Here we&#8217;ll use the MongoDB database, specifically the MongoDB cloud Atlas version, which means our database will be hosted on their cloud.<\/p>\n\n\n\n<h3><a href=\"https:\/\/dev.to\/aviyel\/building-a-fullstack-road-trip-mapper-app-using-the-absolute-power-of-mern-stack-117g#setting-up-mongodb-atlas-cloud-cluster\"><\/a>Setting up MongoDB Atlas cloud cluster<\/h3>\n\n\n\n<p>MongoDB is a document-oriented database that is open-source and cross-platform. MongoDB is a NoSQL database that stores data in JSON-like documents and has optional schemas. All versions were given under the AGPL license prior to October 16, 2018. All versions released after October 16, 2018, including bug fixes for prior versions, are covered by the SSPL license v1. You can also learn more about MongoDB setup and configuration from the following article.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/aviyel.com\/post\/1323\n<\/div><\/figure>\n\n\n\n<p>To set up and start your MongoDB cluster, follow the exact same steps mentioned below.<\/p>\n\n\n\n<p><strong><em>Official MongoDB website<\/em><\/strong>*<br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--z-tapM6I--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637905447164-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Sign-up MongoDB<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--NawkpF6e--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637905489282-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Sign-in to MongoDB<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--oqWmY4uC--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637905522148-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Create a Project<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--XlxmyjGi--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637905836002-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Adding members<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--H-N8kq7A--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637905874939-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Building Database<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--e-Pavx1J--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637906045235-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Creating a Cluster<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--wPu23T8D--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1635322799518-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Selecting a cloud service Provider<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--6AV3XX6G--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1635322998309-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Configuring Security<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--Z0FBpUL---\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637906267111-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Database Deployment to the Cloud<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--yajsRi9i--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637906356590-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Navigate to the network access tab and select &#8220;Add IP address.&#8221;<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--GHji7Nx9--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637906632034-image.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Now, select the Choose a connection method.<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--t7l4mYdR--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1635323638076-image-resized.png\"><\/a><\/p>\n\n\n\n<p><strong><em>Connecting to cluster<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--xWMYRZGK--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637906571369-image.png\"><\/a><\/p>\n\n\n\n<p>Create a new variable called DATABASE_CONNECTION inside index.js . Create a string and paste the copied mongo DB connection URL into it. Now, inside it, type your username and password, removing any brackets and entering your own credentials. We&#8217;ll create environmental variables to safeguard the credential later, but for now, let&#8217;s add it this way. The second thing we&#8217;ll need is a PORT, so just type in 4000 for now. Finally, we&#8217;ll use mongoose to connect to our database, so type in mongoose. connect(), which is a function with two parameters. The DATABASE_CONNECTION will be the first, and the object with two choices will be the second. The first is useNewUrlParser, which we&#8217;ll enable, and the second is useUnifiedTopology, which we&#8217;ll enable as well. These objects are optional, but we will see some errors or warnings on our console. Let&#8217;s chain it with .then() and .catch() inside,then() function. This will simply call the app and invoke listen, leading to two parameters: PORT and the callback function that will be executed if our application is successfully connected to the database. Finally, if the connection to the database is unsuccessful, we will simply console log our error message. Your index.js file should now look something like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/index.js\nconst express = require('express');\n\/\/ NOTE morgan is a logger\nconst morgan = require('morgan');\nconst helmet = require('helmet');\nconst cors = require('cors');\nconst mongoose = require('mongoose');\n\nrequire('dotenv').config();\n\nconst app = express();\n\nconst DATABASE_CONNECTION = process.env.DATABASE_URL;\n\nmongoose.connect(DATABASE_CONNECTION, {\n  useNewUrlParser: true,\n  newUnifiedTopology: true,\n});\n\napp.use(morgan('common'));\napp.use(helmet());\napp.use(cors({\n  origin: process.env.CORS_ORIGIN,\n}));\n\napp.use(express.json());\n\napp.get('\/', (req, res) =&gt; {\n  res.json({\n    message: 'Hello There',\n  });\n});\n\nconst port = process.env.PORT || 4000;\napp.listen(port, () =&gt; {\n  console.log(`Currently Listening at http:\/\/localhost:${port}`);\n});\n<\/code><\/pre>\n\n\n\n<p><strong><em>Insert mongodb+srv into the .env file.<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PORT=4000\nDATABASE_URL=mongodb+srv:\/\/pramit:&lt;password&gt;@cluster0.8tw83.mongodb.net\/myFirstDatabase?retryWrites=true&amp;w=majority\nCORS_ORIGIN=http:\/\/localhost:3000\n<\/code><\/pre>\n\n\n\n<p>We now have successfully connected our server to the database, let&#8217;s create middleware first before we get started on building our backend application&#8217;s routes and database schema. To do so, we&#8217;ll need to create a new file called middlewares.js and within that file, we will create a two function called notFound and errorHandler<\/p>\n\n\n\n<p>and export those functions. So let create notFound middleware so typically this middleware should be the last middleware that is registered so this middleware takes in req, res, and next. Basically, if a request ever made it here, it means we didn&#8217;t locate the route users were searching for, so we&#8217;ll create a variable and send them a message, and then we&#8217;ll pass that to our next middleware, which is errorHander Middleware but before that don&#8217;t forget to pass the response status of 404 as well. Now let&#8217;s make our errorHandler middleware, which has four parameters instead of three, so we&#8217;ll have (error,req, res, next). The first thing we&#8217;ll do is set a status code and check whether it&#8217;s 200 or use the status code that&#8217;s already been specified, and then we&#8217;ll simply set the status code, and then we&#8217;ll respond with some JSON that will display the error message.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/middlewares.js\nconst notFound = (req, res, next) =&gt; {\n  const error = new Error(`Not Found - ${req.originalUrl}`);\n  res.status(404);\n  next(error);\n};\n\nconst errorHandler = (error, req, res, next) =&gt; {\n  const statusCode = res.statusCode === 200 ? 500 : res.statusCode;\n  res.status(statusCode);\n  res.json({\n    message: error.message,\n    stack: process.env.NODE_ENV === \"production\" ? \"nope\" : error.stack,\n  });\n};\n\nmodule.exports = {\n  notFound,\n  errorHandler,\n};\n<\/code><\/pre>\n\n\n\n<p>So, after modifying the middlewares.js file, import and use the middleware as needed in the index.js file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/index.js\nconst express = require(\"express\");\n\/\/ NOTE morgan is a logger\nconst morgan = require(\"morgan\");\nconst helmet = require(\"helmet\");\nconst cors = require(\"cors\");\nconst mongoose = require(\"mongoose\");\n\nrequire(\"dotenv\").config();\n\nconst middlewares = require(\".\/middlewares\");\nconst app = express();\n\nconst DATABASE_CONNECTION = process.env.DATABASE_URL;\n\nmongoose.connect(DATABASE_CONNECTION, {\n  useNewUrlParser: true,\n  newUnifiedTopology: true,\n});\n\napp.use(morgan(\"common\"));\napp.use(helmet());\napp.use(\n  cors({\n    origin: process.env.CORS_ORIGIN,\n  })\n);\n\napp.use(express.json());\n\napp.get(\"\/\", (req, res) =&gt; {\n  res.json({\n    message: \"Hello There\",\n  });\n});\n\napp.use(middlewares.notFound);\napp.use(middlewares.errorHandler);\n\nconst port = process.env.PORT || 4000;\napp.listen(port, () =&gt; {\n  console.log(`Currently Listening at http:\/\/localhost:${port}`);\n});\n<\/code><\/pre>\n\n\n\n<p>let&#8217;s create a LogEntry model. Create a folder called models and inside it, create one file called LogEntry.model.js and within that following file structure your DB schema by defining title, description, comments, image, ratings, latitude and longitude as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/models\/LogEntry.model.js\nconst mongoose = require(\"mongoose\");\nconst { Schema } = mongoose;\n\nconst requiredNumber = {\n  type: Number,\n  required: true,\n};\n\nconst logEntrySchema = new Schema(\n  {\n    title: {\n      type: String,\n      required: true,\n    },\n    description: String,\n    comments: String,\n    image: String,\n    rating: {\n      type: Number,\n      min: 0,\n      max: 10,\n      default: 0,\n    },\n    latitude: {\n      ...requiredNumber,\n      min: -90,\n      max: 90,\n    },\n    longitude: {\n      ...requiredNumber,\n      min: -180,\n      max: 180,\n    },\n    visitDate: {\n      required: true,\n      type: Date,\n    },\n  },\n  {\n    timestamps: true,\n  }\n);\n\nconst LogEntry = mongoose.model(\"collections\", logEntrySchema);\n\nmodule.exports = LogEntry;\n<\/code><\/pre>\n\n\n\n<p>The structure of your files and folders should now look like this.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--r4WNo2SF--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638013845226-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--r4WNo2SF--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638013845226-image.png\" alt=\"Folder Structure\"\/><\/a><\/figure>\n\n\n\n<p>Now that we&#8217;ve successfully created our DB Schema, let&#8217;s get started on creating our routes for our backend application. To do so, we&#8217;ll need to create a new folder inside the src directory and name it as routes Within the routes folder, we will create a js file called logs.routes.js.so first we must import express from &#8220;express&#8221; and also configure our router and import our recently created DB schema. Now we can begin adding our routes to it.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--hi82ItcD--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638017296911-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--hi82ItcD--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638017296911-image.png\" alt=\"Folder Structure\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>const { Router } = require(\"express\");\n\nconst LogEntry = require(\"..\/models\/LogEntry.model.js\");\n\nconst { API_KEY } = process.env;\n\nconst router = Router();\n<\/code><\/pre>\n\n\n\n<p><strong><em>fetches all the pinned location information.<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>router.get(\"\/\", async (req, res, next) =&gt; {\n  try {\n    const entries = await LogEntry.find();\n    res.json(entries);\n  } catch (error) {\n    next(error);\n  }\n});\n<\/code><\/pre>\n\n\n\n<p><strong><em>Insert\/add a pinned location with authorized access<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>router.post(\"\/\", async (req, res, next) =&gt; {\n  try {\n    if (req.get(\"X-API-KEY\") !== API_KEY) {\n      res.status(401);\n      throw new Error(\"Unauthorized Access\");\n    }\n    const logEntry = new LogEntry(req.body);\n    const createdEntry = await logEntry.save();\n    res.json(createdEntry);\n  } catch (error) {\n    if (error.name === \"ValidationError\") {\n      res.status(422);\n    }\n    next(error);\n  }\n});\n<\/code><\/pre>\n\n\n\n<p><strong><em>exporting the router<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module.exports = router;\n<\/code><\/pre>\n\n\n\n<p>Your logs.routes.js should resemble something like this<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/routes\/logs.routes.js\nconst { Router } = require(\"express\");\n\nconst LogEntry = require(\"..\/models\/LogEntry.model.js\");\n\nconst { API_KEY } = process.env;\n\nconst router = Router();\n\nrouter.get(\"\/\", async (req, res, next) =&gt; {\n  try {\n    const entries = await LogEntry.find();\n    res.json(entries);\n  } catch (error) {\n    next(error);\n  }\n});\n\nrouter.post(\"\/\", async (req, res, next) =&gt; {\n  try {\n    if (req.get(\"X-API-KEY\") !== API_KEY) {\n      res.status(401);\n      throw new Error(\"Unauthorized Access\");\n    }\n    const logEntry = new LogEntry(req.body);\n    const createdEntry = await logEntry.save();\n    res.json(createdEntry);\n  } catch (error) {\n    if (error.name === \"ValidationError\") {\n      res.status(422);\n    }\n    next(error);\n  }\n});\n\nmodule.exports = router;\n<\/code><\/pre>\n\n\n\n<p><strong><em>Now, update your .env file<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NODE_ENV=production\nPORT=4000\nDATABASE_URL=mongodb+srv:\/\/pramit:&lt;password&gt;@cluster0.8tw83.mongodb.net\/myFirstDatabase?retryWrites=true&amp;w=majority\nCORS_ORIGIN=http:\/\/localhost:3000\nAPI_KEY=roadtripmapper\n<\/code><\/pre>\n\n\n\n<p>Let&#8217;s get started by importing the logs routes into your index.js file. We can now connect map pinned log info to our application using express middleware. Finally, your root index.js file should be like the following.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/index.js\nconst express = require(\"express\");\n\/\/ NOTE morgan is a logger\nconst morgan = require(\"morgan\");\nconst helmet = require(\"helmet\");\nconst cors = require(\"cors\");\nconst mongoose = require(\"mongoose\");\n\nrequire(\"dotenv\").config();\n\nconst middlewares = require(\".\/middlewares\");\nconst logs = require(\".\/routes\/logs.routes.js\");\nconst app = express();\n\nconst DATABASE_CONNECTION = process.env.DATABASE_URL;\n\nmongoose.connect(DATABASE_CONNECTION, {\n  useNewUrlParser: true,\n  newUnifiedTopology: true,\n});\n\napp.use(morgan(\"common\"));\napp.use(helmet());\napp.use(\n  cors({\n    origin: process.env.CORS_ORIGIN,\n  })\n);\n\napp.use(express.json());\n\napp.get(\"\/\", (req, res) =&gt; {\n  res.json({\n    message: \"Hello There\",\n  });\n});\n\napp.use(\"\/api\/logs\", logs);\n\napp.use(middlewares.notFound);\napp.use(middlewares.errorHandler);\n\nconst port = process.env.PORT || 4000;\napp.listen(port, () =&gt; {\n  console.log(`Currently Listening at http:\/\/localhost:${port}`);\n});\n<\/code><\/pre>\n\n\n\n<p>After restarting the server, you should see something like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--Fq5ljdmU--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036953812-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--Fq5ljdmU--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036953812-image.png\" alt=\"Server Running\"\/><\/a><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h3><a href=\"https:\/\/dev.to\/aviyel\/building-a-fullstack-road-trip-mapper-app-using-the-absolute-power-of-mern-stack-117g#setting-up-the-frontend-with-react\"><\/a>Setting up the frontend with react<\/h3>\n\n\n\n<p>In the next step let&#8217;s start with the frontend and build it with react. The first thing you need to do is install Node.js if it isn&#8217;t already installed on your machine. So, go to the Node.js official website and download the most recent version. You&#8217;ll require Node js to utilize the node package manager, generally known as NPM. Now navigate to the client folder in your favorite code editor. Visual Studio Code will be my tool of choice. Then, in the integrated terminal, type npx create-react-app. This command will create a client application in the current directory with the name client.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_adxZapT--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638019632382-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_adxZapT--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638019632382-image.png\" alt=\"create-react-app\"\/><\/a><\/figure>\n\n\n\n<p>There&nbsp;is&nbsp;a&nbsp;separate&nbsp;article&nbsp;where&nbsp;you&nbsp;may&nbsp;learn&nbsp;everything&nbsp;there&nbsp;is&nbsp;to&nbsp;know&nbsp;about<\/p>\n\n\n\n<p>cleaning up boilerplate react project.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/aviyel.com\/post\/1190\n<\/div><\/figure>\n\n\n\n<p>It&#8217;s time to install some packages within react-boilerplate now that you&#8217;ve installed and cleaned it. so copy and paste the following command into your terminal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm i react-hook-form react-map-gl react-rating-stars-component react-responsive-animate-navbar\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--WGevhfqS--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638024929694-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--WGevhfqS--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638024929694-image-resized.png\" alt=\"Dependencies\"\/><\/a><\/figure>\n\n\n\n<ul><li>react-hook-form: Performant, flexible, and extensible forms library for React Hooks.<\/li><li>react-map-gl: react-map-gl is a suite of React components designed to provide a React API for Mapbox GL JS-compatible libraries<\/li><li>react-rating-stars-component: Simple star rating component for your React projects.<\/li><li>react-responsive-animate-navbar : simple, flexible &amp; completely customizable responsive navigation bar component.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rLys1zl6--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638025122874-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rLys1zl6--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638025122874-image-resized.png\" alt=\"Dependencies Installation\"\/><\/a><\/figure>\n\n\n\n<p>After installing all these packages your packge.json file of the client should look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--zQb91OUz--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638025324267-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--zQb91OUz--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638025324267-image-resized.png\" alt=\"Package json\"\/><\/a><\/figure>\n\n\n\n<p>Let&#8217;s construct two separate folders \/components inside the components folder after we&#8217;ve installed all of our project&#8217;s dependencies and name it as RoadTripNav and TripEntryForm .<\/p>\n\n\n\n<p>Your file and folder structure should look something like this once you&#8217;ve added all of your components.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--0ljpsYTM--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638026533825-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--0ljpsYTM--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638026533825-image.png\" alt=\"Folder Structure\"\/><\/a><\/figure>\n\n\n\n<p>Now that you have all of the project&#8217;s components set up, it&#8217;s time to start coding. First, import the ReactNavbar from &#8220;react-responsive-animate-navbar&#8221; and customize the color of your navbar, add the logo to the public folder and import it directly, and don\u2019t forget to add some social links as well. The following is an example of how the code should appear.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rMvXbb7p--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036022672-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rMvXbb7p--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036022672-image.png\" alt=\"RoadTripNavComponent\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ components\/RoadTripNav\nimport React from \"react\";\nimport * as ReactNavbar from \"react-responsive-animate-navbar\";\n\/\/ import roadTripSvg from \"..\/..\/assets\/roadtrip.svg\";\n\nconst RoadTripNav = () =&gt; {\n  return (\n    &lt;ReactNavbar.ReactNavbar\n      color=\"rgb(25, 25, 25)\"\n      logo=\".\/logo.svg\"\n      menu={&#91;]}\n      social={&#91;\n        {\n          name: \"Twitter\",\n          url: \"https:\/\/twitter.com\/pramit_armpit\",\n          icon: &#91;\"fab\", \"twitter\"],\n        },\n      ]}\n    \/&gt;\n  );\n};\n\nexport default RoadTripNav;\n<\/code><\/pre>\n\n\n\n<p>Before we go any further, let&#8217;s set up our Mapbox. First, go to the Mapbox site and log in or sign up if you don&#8217;t already have an account. Next, create your own custom map style in the Mapbox Studio and publish it. Finally, go back to the dashboard and copy the default public API key provided by MapBox.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--0U24qm4o--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637907686658-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--0U24qm4o--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637907686658-image-resized.png\" alt=\"Mapbox\"\/><\/a><\/figure>\n\n\n\n<p><strong><em>Login or create your MapBox account<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--XoYP0YOF--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637907709168-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--XoYP0YOF--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637907709168-image-resized.png\" alt=\"Mapbox login\"\/><\/a><\/figure>\n\n\n\n<p><strong><em>Click on design a custom map style<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--FiYiw1jh--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637923672745-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--FiYiw1jh--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637923672745-image.png\" alt=\"Mapbox studio\"\/><\/a><\/figure>\n\n\n\n<p><strong><em>Customize your own style of the map inside the Mapbox studio<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--fzikZIJL--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637923619968-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--fzikZIJL--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637923619968-image-resized.png\" alt=\"MapBox studio Editor\"\/><\/a><\/figure>\n\n\n\n<p><strong><em>Copy the default public token<\/em><\/strong><br><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--oMO0ArWf--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637923829522-image-resized.png\"><\/a><\/p>\n\n\n\n<p>After you&#8217;ve successfully obtained your public token, go to the env file or create one if you don\u2019t have and after that create a variable named as REACT_APP_MAPBOX_TOKEN, then paste that token into that variable. This is what your env file should look like.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>REACT_APP_MAPBOX_TOKEN= ************************************ \/\/ add token\n<\/code><\/pre>\n\n\n\n<p>Before we go any further, let&#8217;s make an api and styles folder in our root source directory. Inside the api folder, make a API.js file, and inside the styles folder, make a index.css file where all our styles of the application will be added. This is how your folder structure should appear.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--cgwIX-k9--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638028733936-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--cgwIX-k9--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638028733936-image.png\" alt=\"Folder Structure\"\/><\/a><\/figure>\n\n\n\n<p>Now go to the newly created API file and construct two functions called &#8220;listLogEntries&#8221; to collect all the log entries from the backend and &#8220;createLogEntries&#8221; to create or send the post request \/ post the entries to the backend, as well as export these functions. Also, don&#8217;t forget to include the URL where your server is running.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rS-lFTd_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036093022-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--rS-lFTd_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036093022-image.png\" alt=\"API\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/api\/API.js\nconst API_URL = \"http:\/\/localhost:4000\";\n\/\/ const API_URL = window.location.hostname === \"localhost\" ? \"http:\/\/localhost:4000\" : \"https:\/\/road-trip-map-mern.herokuapp.com\" ;\n\nexport async function listLogEntries() {\n  const response = await fetch(`${API_URL}\/api\/logs`);\n  \/\/ const json = await response.json();\n  return response.json();\n}\n\nexport async function createLogEntries(entry) {\n  const api_key = entry.api_key;\n  delete entry.api_key;\n  const response = await fetch(`${API_URL}\/api\/logs`, {\n    method: \"POST\",\n    headers: {\n      \"content-type\": \"application\/json\",\n      \"X-API-KEY\": api_key,\n    },\n    body: JSON.stringify(entry),\n  });\n  \/\/ const json = await response.json();\n  \/\/ return response.json();\n  let json;\n  if (response.headers.get(\"content-type\").includes(\"text\/html\")) {\n    const message = await response.text();\n    json = {\n      message,\n    };\n  } else {\n    json = await response.json();\n  }\n  if (response.ok) {\n    return json;\n  }\n  const error = new Error(json.message);\n  error.response = json;\n  throw error;\n}\n<\/code><\/pre>\n\n\n\n<p>Let&#8217;s make a submission form for the pinned map location. To do so, open the TripEntryForm component from the component folder we previously made, import the useForm hook from react-hook-form, import createLogentries from api, and then import the useState hook from the React library because this hook will enable us to integrate the state into our functional component. useState(), unlike state in class components, does not work with object values. If necessary, we can use primitives directly and create multiple react hooks for multiple variables. Now, create two states: loading and error, and then destructure register and handleSubmit from the useForm() hook from &#8220;react-hook-form&#8221; library.After you&#8217;ve completed that, it&#8217;s time to craft our form, but first let&#8217;s create a function to handle our submit request. To do so, create an asynchronous onSubmit function and inside it, simply create a try-catch block. Inside the try block set the loading to true, configure the latitude and longitude, console log the data, and invoke the onClose function, and finally inside the catch block, pass the error message to the error state, set the loading to false and simply console log the error message and then simply create a form inside the return statement exactly shown in the code below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--EF-iElcY--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036159120-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--EF-iElcY--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036159120-image.png\" alt=\"TripEntry Form\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ components\/TripEntryForm.js\nimport React, { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { createLogEntries } from \"..\/..\/api\/API\";\nimport \".\/TripEntryForm.css\";\n\nconst TripEntryForm = ({ location, onClose }) =&gt; {\n  const &#91;loading, setLoading] = useState(false);\n  const &#91;error, setError] = useState(\"\");\n\n  const { register, handleSubmit } = useForm();\n\n  const onSubmit = async (data) =&gt; {\n    try {\n      setLoading(true);\n      data.latitude = location.latitude;\n      data.longitude = location.longitude;\n      const created = await createLogEntries(data);\n      console.log(created);\n      onClose();\n    } catch (error) {\n      setError(error.message);\n      console.error(error);\n      setLoading(false);\n    }\n  };\n\n  return (\n    &lt;form onSubmit={handleSubmit(onSubmit)} className=\"trip-form\"&gt;\n      {error ? &lt;h3 className=\"error-message\"&gt;{error}&lt;\/h3&gt; : null}\n      &lt;label htmlFor=\"api_key\"&gt;Enter Password&lt;\/label&gt;\n      &lt;input\n        type=\"password\"\n        name=\"api_key\"\n        placeholder=\"For demo, password =&gt; {roadtripmap} \"\n        required\n        ref={register}\n      \/&gt;\n\n      &lt;label htmlFor=\"title\"&gt;Title&lt;\/label&gt;\n      &lt;input name=\"title\" placeholder=\"Title\" required ref={register} \/&gt;\n\n      &lt;label htmlFor=\"comments\"&gt;Comments&lt;\/label&gt;\n      &lt;textarea\n        name=\"comments\"\n        placeholder=\"Comments\"\n        rows={3}\n        ref={register}\n      &gt;&lt;\/textarea&gt;\n\n      &lt;label htmlFor=\"description\"&gt;Description&lt;\/label&gt;\n      &lt;textarea\n        name=\"description\"\n        placeholder=\"Describe your journey\"\n        rows={4}\n        ref={register}\n      &gt;&lt;\/textarea&gt;\n\n      &lt;label htmlFor=\"image\"&gt;Image&lt;\/label&gt;\n      &lt;input name=\"image\" placeholder=\"Image URL\" ref={register} \/&gt;\n\n      &lt;label htmlFor=\"rating\"&gt;Rating (1 - 10)&lt;\/label&gt;\n      &lt;input name=\"rating\" type=\"number\" min=\"0\" max=\"10\" ref={register} \/&gt;\n\n      &lt;label htmlFor=\"visitDate\"&gt;Visit Date&lt;\/label&gt;\n      &lt;input name=\"visitDate\" type=\"date\" required ref={register} \/&gt;\n\n      &lt;button disabled={loading}&gt;\n        &lt;span&gt;{loading ? \"Submitting...\" : \"Submit your Trip\"}&lt;\/span&gt;\n      &lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n};\n\nexport default TripEntryForm;\n<\/code><\/pre>\n\n\n\n<p>Also, don&#8217;t forget to add the TripEntryForm styles inside that very own component folder and name it as TripEntryForm.css and paste the exact CSS code as mentioned below<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--auefFJZG--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036209467-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--auefFJZG--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036209467-image.png\" alt=\"TripEntry Form style\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/TripEntryForm.css\n@import url(\"https:\/\/fonts.googleapis.com\/css2?family=Fredoka+One&amp;family=Poppins:ital,wght@0,200;0,400;1,200;1,300&amp;family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&amp;display=swap\");\n\n.trip-form label {\n  margin: 0.5rem 0;\n  display: block;\n  width: 100%;\n  color: rgb(255, 255, 255);\n  font-family: \"Fredoka One\", cursive;\n}\n.trip-form input {\n  margin: 0.5rem 0;\n  background-color: #2c2e41;\n  border-radius: 5px;\n  border: 0;\n  box-sizing: border-box;\n  color: rgb(255, 255, 255);\n  font-size: 12px;\n  height: 100%;\n  outline: 0;\n  padding: 10px 5px 10px 5px;\n  width: 100%;\n  font-family: \"Fredoka One\", cursive;\n}\n\n.trip-form textarea {\n  margin: 0.5rem 0;\n  background-color: #2c2e41;\n  border-radius: 5px;\n  border: 0;\n  box-sizing: border-box;\n  color: rgb(255, 255, 255);\n  font-size: 12px;\n  height: 100%;\n  outline: 0;\n  padding: 10px 5px 10px 5px;\n  width: 100%;\n  font-family: \"Fredoka One\", cursive;\n}\n\n.error-message {\n  color: red;\n}\n\n.trip-form button {\n  background-color: #fb5666;\n  border-radius: 12px;\n  border: 0;\n  box-sizing: border-box;\n  color: #eee;\n  cursor: pointer;\n  font-size: 18px;\n  height: 50px;\n  margin-top: 38px;\n  outline: 0;\n  text-align: center;\n  width: 100%;\n}\n\nbutton span {\n  position: relative;\n  z-index: 2;\n}\n\nbutton:after {\n  position: absolute;\n  content: \"\";\n  top: 0;\n  left: 0;\n  width: 0;\n  height: 100%;\n  transition: all 2.35s;\n}\n\nbutton:hover {\n  color: #fff;\n}\n\nbutton:hover:after {\n  width: 100%;\n}\n\n.small_description {\n  font-size: 60px;\n}\n<\/code><\/pre>\n\n\n\n<p>Now go to this repo and download all of the SVG files that are available there.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/github.com\/pramit-marattha\/road-trip-mapper-mern-app\/tree\/main\/client\/src\/assets\n<\/div><\/figure>\n\n\n\n<p>After you&#8217;ve downloaded all of the svg files, go to the main app component, and begin importing all of the key requirements from the libraries we previously installed, such as ReactMapGl, marker, and popup from the &#8220;react-map-gl&#8221; library, import all of the components as well as svgs from the assets folder, and finally create four state logEntries whose initial value is empty array, showPopup whose initial value is an empty object, addEntryLocation has a default value of null, and for viewport specify the initial value exactly like the code mentioned below or you can add whatever you want. Create an asynchronous function called getEntries that asynchronously calls the listLogEntries function that was previously established within the api file and whose main task is to retrieve all of the entries made by the users and feed them to the logEntries state and then call that function inside the useEffect() hook by using this Hook, you tell React that your component needs to do something after render.<\/p>\n\n\n\n<p>React will remember the function you passed (we\u2019ll refer to it as our \u201ceffect\u201d), and call it later after performing the DOM updates. To this effect, we set the document title, but we could also perform data fetching or call some other imperative API. Placing useEffect() inside the component lets us access the count state variable (or any props) right from the effect. We don\u2019t need a special API to read it \u2014 it\u2019s already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.useEffect() the hook is somewhat similar to the life-cycle methods that we are aware of for class components. It runs after every render of the component including the initial render. Hence it can be thought of as a combination of componentDidMount, componentDidUpdate, and componentWillUnmount.If we want to control the behavior of when the effect should run (only on initial render, or only when a particular state variable changes), we can pass in dependencies to the effect to do so. This hook also provides a clean-up option to allow cleaning up of resources before the component is destroyed. basic syntax of the effect: useEffect(didUpdate) .<\/p>\n\n\n\n<p>Create a function named showMarkerPopup and provide the event parameters to it. Inside that function, destruct the latitude and longitude from &#8220;event.lngltd&#8221; and pass it to addEntryLocation state. Finally, employ all of the imported components within our return statement by simply following the code shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--P_Eel5Gd--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036249267-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--P_Eel5Gd--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036249267-image.png\" alt=\"App component\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/src\/app.js\nimport * as React from \"react\";\nimport { useState, useEffect } from \"react\";\nimport ReactMapGL, { Marker, Popup } from \"react-map-gl\";\nimport { listLogEntries } from \".\/api\/API\";\nimport MapPinLogo from \".\/assets\/mapperPin.svg\";\nimport MarkerPopup from \".\/assets\/MarkerPopup.svg\";\nimport TripEntryForm from \".\/components\/TripEntryForm\";\nimport ReactStars from \"react-rating-stars-component\";\nimport RoadTripNav from \".\/components\/RoadTripNav\/RoadTripNav\";\n\nconst App = () =&gt; {\n  const &#91;logEntries, setLogEntries] = useState(&#91;]);\n  const &#91;showPopup, setShowPopup] = useState({});\n  const &#91;addEntryLocation, setAddEntryLocation] = useState(null);\n  const &#91;viewport, setViewport] = useState({\n    width: \"100vw\",\n    height: \"100vh\",\n    latitude: 27.7577,\n    longitude: 85.3231324,\n    zoom: 7,\n  });\n\n  const getEntries = async () =&gt; {\n    const logEntries = await listLogEntries();\n    setLogEntries(logEntries);\n    console.log(logEntries);\n  };\n\n  useEffect(() =&gt; {\n    getEntries();\n  }, &#91;]);\n\n  const showMarkerPopup = (event) =&gt; {\n    console.log(event.lngLat);\n    const &#91;longitude, latitude] = event.lngLat;\n    setAddEntryLocation({\n      longitude,\n      latitude,\n    });\n  };\n\n  return (\n    &lt;&gt;\n      &lt;RoadTripNav \/&gt;\n      &lt;ReactMapGL\n        {...viewport}\n        mapStyle=\"mapbox:\/\/styles\/pramitmarattha\/ckiovge5k3e7x17tcmydc42s3\" \n        mapboxApiAccessToken={process.env.REACT_APP_MAPBOX_TOKEN}\n        onViewportChange={(nextViewport) =&gt; setViewport(nextViewport)}\n        onDblClick={showMarkerPopup}\n      &gt;\n        {logEntries.map((entry) =&gt; (\n          &lt;React.Fragment key={entry._id}&gt;\n            &lt;Marker latitude={entry.latitude} longitude={entry.longitude}&gt;\n              &lt;div\n                onClick={() =&gt;\n                  setShowPopup({\n                    \/\/ ...showPopup,\n                    &#91;entry._id]: true,\n                  })\n                }\n              &gt;\n                &lt;img\n                  className=\"map-pin\"\n                  style={{\n                    width: `${5 * viewport.zoom}px`,\n                    height: `${5 * viewport.zoom}px`,\n                  }}\n                  src={MapPinLogo}\n                  alt=\"Map Pin Logo\"\n                \/&gt;\n              &lt;\/div&gt;\n            &lt;\/Marker&gt;\n            {showPopup&#91;entry._id] ? (\n              &lt;Popup\n                latitude={entry.latitude}\n                longitude={entry.longitude}\n                closeButton={true}\n                closeOnClick={false}\n                dynamicPosition={true}\n                onClose={() =&gt; setShowPopup({})}\n                anchor=\"top\"\n              &gt;\n                &lt;div className=\"popup\"&gt;\n                  &lt;ReactStars\n                    count={10}\n                    value={entry.rating}\n                    size={29}\n                    activeColor=\"#ffd700\"\n                  \/&gt;\n                  &lt;div className=\"popup_image\"&gt;\n                    {entry.image &amp;&amp; &lt;img src={entry.image} alt={entry.title} \/&gt;}\n                  &lt;\/div&gt;\n                  &lt;h3&gt;{entry.title}&lt;\/h3&gt;\n                  &lt;p&gt;{entry.comments}&lt;\/p&gt;\n                  &lt;small&gt;\n                    Visited :{\" \"}\n                    {new Date(entry.visitDate).toLocaleDateString(\"en-US\", {\n                      weekday: \"long\",\n                      year: \"numeric\",\n                      month: \"long\",\n                      day: \"numeric\",\n                    })}\n                  &lt;\/small&gt;\n                  &lt;p&gt;Ratings: {entry.rating}&lt;\/p&gt;\n                  &lt;div className=\"small_description\"&gt;{entry.description}&lt;\/div&gt;\n                &lt;\/div&gt;\n              &lt;\/Popup&gt;\n            ) : null}\n          &lt;\/React.Fragment&gt;\n        ))}\n        {addEntryLocation ? (\n          &lt;&gt;\n            &lt;Marker\n              latitude={addEntryLocation.latitude}\n              longitude={addEntryLocation.longitude}\n            &gt;\n              &lt;div&gt;\n                &lt;img\n                  className=\"map-pin\"\n                  style={{\n                    width: `${8 * viewport.zoom}px`,\n                    height: `${8 * viewport.zoom}px`,\n                  }}\n                  src={MarkerPopup}\n                  alt=\"Map Pin Logo\"\n                \/&gt;\n              &lt;\/div&gt;\n              {\/* &lt;div style={{color:\"white\"}}&gt;{entry.title}&lt;\/div&gt; *\/}\n            &lt;\/Marker&gt;\n\n            &lt;Popup\n              latitude={addEntryLocation.latitude}\n              longitude={addEntryLocation.longitude}\n              closeButton={true}\n              closeOnClick={false}\n              dynamicPosition={true}\n              onClose={() =&gt; setAddEntryLocation(null)}\n              anchor=\"top\"\n            &gt;\n              &lt;div className=\"popup\"&gt;\n                &lt;TripEntryForm\n                  onClose={() =&gt; {\n                    setAddEntryLocation(null);\n                    getEntries();\n                  }}\n                  location={addEntryLocation}\n                \/&gt;\n              &lt;\/div&gt;\n            &lt;\/Popup&gt;\n          &lt;\/&gt;\n        ) : null}\n      &lt;\/ReactMapGL&gt;\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>The very final step is to add all of the styles to our project, which can be done by going to our previously established styles folder and copying and pasting the following mentioned code into the index.css file.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--kJntPAM2--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036274330-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--kJntPAM2--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036274330-image.png\" alt=\"index css\"\/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* styles\/index.css *\/\n@import url(\"https:\/\/fonts.googleapis.com\/css2?family=Fredoka+One&amp;family=Poppins:ital,wght@0,200;0,400;1,200;1,300&amp;family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&amp;display=swap\");\n\nbody {\n  margin: 0;\n  font-family: \"Fredoka One\", cursive;\n  height: 100vh;\n  width: 100vw;\n  overflow: hidden;\n}\n\ncode {\n  font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n    monospace;\n}\n\n.map-pin {\n  position: absolute;\n  transform: translate(-50%, -100%);\n  z-index: -1;\n}\n\n.popup {\n  width: 20vw;\n  height: auto;\n  padding: 1rem;\n  background-color: #8661d1;\n  border-radius: 5px;\n  z-index: 999;\n}\n\n.popup img {\n  width: 40%;\n  height: auto;\n  border-radius: 5%;\n  justify-content: center;\n  align-items: center;\n  margin: 0 auto;\n  padding-top: 1rem;\n}\n\n.popup_image {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.small_description {\n  font-size: 1.5rem;\n  color: #fff;\n  border-radius: 5px;\n  z-index: 999;\n}\n\nbutton {\n  border: none;\n  color: #fa5252;\n  padding-right: 1rem;\n  border-radius: 50%;\n  font-size: 4rem;\n  margin-top: 0.2rem;\n  height: auto;\n  cursor: pointer;\n}\n<\/code><\/pre>\n\n\n\n<p>Finally, start both the client and the server.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--CcZmVDcq--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036698778-image.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--CcZmVDcq--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1638036698778-image.png\" alt=\"React Running\"\/><\/a><\/figure>\n\n\n\n<h2><a href=\"https:\/\/dev.to\/aviyel\/building-a-fullstack-road-trip-mapper-app-using-the-absolute-power-of-mern-stack-117g#application-up-and-running\"><\/a>Application up and running<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--8zGgghdw--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933630247-image-resized.png\"><img src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--8zGgghdw--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/aviyel.com\/assets\/uploads\/files\/1637933630247-image-resized.png\" alt=\"Demo\"\/><\/a><\/figure>\n\n\n\n<p>This application&#8217;s entire source code is available here.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/github.com\/aviyeldevrel\/devrel-tutorial-projects\/tree\/main\/MERN-roadtrip-mapper\n<\/div><\/figure>\n\n\n\n<p>Main article available here =&gt;&nbsp;<a href=\"https:\/\/aviyel.com\/post\/1430\/fullstack-road-trip-mapper-app-built-using-mern-stack?utm_source=dev_to&amp;utm_medium=articles_project_tutorials&amp;utm_campaign=post_1430\">https:\/\/aviyel.com\/post\/1430<\/a><\/p>\n\n\n\n<p>Happy Coding!!<\/p>\n\n\n\n<p>Follow&nbsp;<a href=\"https:\/\/twitter.com\/AviyelHq\">@aviyelHQ<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/aviyel.com\/discussions\">sign-up<\/a>&nbsp;on Aviyel for early access if you are a project maintainer, contributor, or just an Open Source enthusiast.<\/p>\n\n\n\n<p>Join Aviyel&#8217;s Discord =&gt;&nbsp;<a href=\"https:\/\/discord.gg\/TbfZmbvnN5\">Aviyel&#8217;s world<\/a><\/p>\n\n\n\n<p>Twitter =&gt;[<a href=\"https:\/\/twitter.com\/AviyelHq\">https:\/\/twitter.com\/AviyelHq<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article concentrates on the most critical tasks and concepts for better understanding and building MERN stack applications from the ground up. It&#8217;s for folks who are serious about learning about the MERN stack and want to concentrate on the essentials.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[30],"tags":[186],"_links":{"self":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2275"}],"collection":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2275"}],"version-history":[{"count":1,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2275\/revisions"}],"predecessor-version":[{"id":2276,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2275\/revisions\/2276"}],"wp:attachment":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}