Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 7

=======================

==== INITIAL SETUP ====


=======================

Frontend and Backend Folders


in Backend folder, npm init
npm install express cors mysql2
(cors help connecting fronend of react to backend)
index.js in backend, which is main entry point for api
if we change the name of index.js, change it also in package.json ("main":
"index.js")

installing express for front end


nodemon for constant refresh
install sequelize sequelize-cli
in backend folder > npx sequelize init
delete seeders migrations folders

to create table in database through commandline, in the models folder we create the
file with the name of the table.

create a variable and define it using sequelize.define, this is defining the table.

inside the definition, we need to define the columns we want in the table.

at the end of the file then return the same variable.

Since this is an export module as we defined in the first line, so now we need to
go to index.js to use it.

in index.js we require the whole "models" folder in which all the table files are
present.

so now if we the sequelize sync function before app.listen it will generate the
table. so the main sync fucntion is:

db.sequelize.sync().then => {}

now we can just use app.listen inside the { } for this to work.

Now everytime the api is called, it will check to see if all the files/tables in
the models folder exist in the database, if not then crate them.

to connect sequelize to the database, so the settings in config.json file and only
in the "development" tag

run the app and it will create the table.

=======================================================
==== GET AND POST REQUESTS AND CREATING END POINTS ====
=======================================================

To create get and post requests, we first need to create end points in the api. We
use express routing system for that.
an example route is localhost:3001/submit to handle this, we need to create an
endpoint in the api.
so we create a routes folder in the backend that will contain all the routes
and then we use express built in routing system using express.Router()

and then we simply export the router and access it index.js (our main api)

inside this file, we can write router.get and router.post requests

but for our main index.js we need to use the exported variable router, and use it
as a middleware. To do that we first require the file/route from routes folder, and
then use the middleware:

const expensesRouter = require('./routes/Expenses')


app.use ("/route-we-want-to-use", expensesRouter

since we have defined /path in the app.use in index.js file, so in our routes file
we only define it / as every request is already in the expenseRouter

Now to use the GET and POST requests, we go into the router file and define the get
as following example:

router.get("/",(req,res)=>{
res.send("test");
});

this only tests the get requests and is not a good methos to test requests, to test
the post requests we need to some data to our backend. so either we create a
form/frontend and send some data through it or we can use an api tests to send the
data to backend e.g. Postman or insomnia

res.send("test"); returns as a web page, but if we are to return some data, we


return it as a json, so to return a json:

router.get("/",(req,res)=>{
res.json("test");
});

GET requests are to get data fromt the databse


POST requests are to send data to the database

=============for POST request:

router.post("/",(req,res)=>

We need to know how we are going to receive the data from the front end, so
that we can use it here inside the function, then it can be used or to be sent to
DB.
In our case its going to be a json consisting of item, price, date, username
we can access this data useing req.body or store it in a variable like
const expense = req.body and then use expense everywhere e.g expense.title

but we need to get the expense data from frontend in the form a varible, in our
case is an object consisting of details (item, price, date, username)

So to use the same format of the data, as we defined while creating table, we
require the relevant file from models and use it. with following at the top:
const {Expenses}=require('../models')
Now we have grabbed Expenses at the top, so in the code here, we can use the
sequelize function crate() and and we pass it the same object as we created in the
table/models file.

so

const expense = req.body;


Expenses.create(expense);

as the fronend will send the expense object in the same format as we created the
table in models file.

But we need this function to be async, meaning that we need to wait for the data to
be inserted before moving forward with the request. So async before the function
start and await before using create function of sequelize.

Now since we do not have a front end yet, we can use insomnia to send a POST
request with a json which as same data as we need at our backend.

{
"item":"milk",
"price":"400",
"date":"2023-09-17",
"username":"ahsan"
}

This will not work as req.body is getting unparsed data from frontend. and express
cannot work with that. To solve that, we go our main index.js api and use
app.use(express.json());

});

=============for GET request:

Now that we have inserted some data in the database using POST request, we can
actually get it or all the data from database in the get request section.

findALL function of sequelize can do that like:


const listExpenses = Expenses.findAll();
but again do that with async and await

Now the GET and POST request working, and we can send and receive data using
insomnia request generator. Now we can creata a front end to actually send /
receive data using frontend.

============================================================
==== CREATING REACT APP, CONNECTING FRONTEND TO BACKEND ====
============================================================

Now we do all the work in frontend folder.

npx create-react-app app-name


to create in the default frontend folder, we use: npx create-react-app .

to start the react app, we use npm start, and it auto loads on localhost:3000
and it will generate a sample app with some files.
We delete app.test.js index.css logo.svg setupTests.js
and the css is in the app.css
We can use css with
import './index.css'; so we delete this line from index.js also as we deleted
index.css

App.js is kind of our entry point of the application, so we delete most its
contents also.

Now in the frontend we create API requests to our API that we made in the backend.
For example, to load data from the databse, i.e. to list data on the webpage, we
need to access the GET endpoint that we created in the "backend>routes>Expenses"
Because that GET request sends a list of all the object in the databse as a json.
We can use that data in our react app.

To send GET POST requests from react app to our API, we use a library axios.
(for this purpose FETCH api can be used which comes with javascript)

npm install axios


on the front end.

And then in the app.js, we import it: import axios from 'axios';

to make a simple get request using axios, we can use axios.get();

Say we want to list something from databse everytime a page loads, we need to tell
the page to send the get request using axios to backend everytime the page
loads/refreshs. Otherwise, we could create a button and send the get request using
that.

To use axios.get on every page load, we can use a react hook useEffect which allows
us to run a function immediately when a page renders. Use:

useEffect(()=>{logic we want to run when page re-renders},[list of states which


will trigger the function to run again])

in our case we leave it as an empty array and it will run once when the page
refreshes. (READ ON IT)

after DOT, we tell the computer what to do with a data. Since this is a promise so
we use .then (READ ON THE PROMISE)

so inside .then(), we can pass an anonymous function that runs after we receive the
data.

The data that we receive will be passed to this anonymous function as an argument.
and then inside the function we use the response the way we want.

useEffect(()=>{
axios.get("http://localhost:3001/expenses").then((response)=>{
console.log(response);
});
},[]);

If we see console of the webpage it will give an error, and wont show data. In
simple words, we need to whitelise our own computer for our API so that it can
allow it access the API to make the request. For this we use cors.
so in the backend API (index.js) import cors. and the we use it as a middleware and
it will automatically whitelise the API requests from react app which is running on
the same computer.

This will now show data on console.

To display it on the webpage, we need to creare a state. to do that we use another


hook from react called useState.

We create state which contains list of all the expenses that we received in the
response of GET request from our API.

const [listOfExpenses, setListOfExpenses] = useState([]);

setListofExpenses is the function to change listOfExpenses, and we pass an array in


useState function, because our API returns a list, and set it empty at start.

now when we recieve the data, we pass this data to the function setListOfExpenses
as setListOfExpenses(response.data) so finally:

setListOfExpenses(response.data);

Now we have a state which contains response from the API request. and we can use
this state to show received data in our application.

To navigate through this list/state inside the react, we use map function to map
through every single element.

listOfExpenses.map()

listOfExpenses.map(() => { })

inside the map function we need to pass two argument, value and key.
The key represents index in the array in which the element exists and the value is
the value of the elemenet itself.

Now inside the { } we write what we want to do on each value i.e. for each element.
For example if we return a div as:

return <div> {value.item} </div>;

it will loop through all the elements, and every time it will list the value.item
i.e. item from the object value. This will display all the items name in the table
from database.

return <div className="App">


{listOfExpenses.map((value,key) =>
{
return <div> {value.item} </div>;
})}
</div>;

We can return a div for each element in the list.

===============================================================
==== USING REACT ROUTER DOM FOR DIFFERENT ROUTERS AND URLS ====
===============================================================

Instead of writing all our code in app.js like we previously did, we can create
routes for different URLS in the front end as well.
so we npm install reac-router-dom inside client

so inside src folder we create a pages folder which is going to have all the pages
and links to which we will create the routes.

First we create the main page calling it Home.js

(ES7+ React/Redux/React-Native snippets Extensions allows creating react app code


wioth rfce shortcut)

We remove all code related to loading expenses from app.js and move it to home.js

In the main app.js we will have structure/definition of our routes.

To do that we import few things from react-router-dom


BrowserRouter as Router import helps use Router in code in place BrowserRouter

Now to create Routes:

<Router>
<Routes>
<Route path="/" element={<Mainpage/>} />
</Routes>
</Router>

==Switch syntaxc has been changed with Routes in new router-dom

To add links in the page, we also import Link from react-router-dom

<Link to="/">Expenses List</Link>


<Link to="/newentry">New Entry</Link>

to create forms, we import a library Formik. it can create form fields without
trraditional html tags and also helps form validation i.e. validate data easily
i.e. catch errors while filling.

to use this we import few things from formik i.e. Formik, Form, Field, ErrorMessage

<Formik initialValues={} onSubmit={} validationSchema={}>


<Form>
<Field id="inputTextBox" name="title" />
</Form>
</Formik>

We need to pass the arguments to Formik tags which initially we do not have.
Then we create Form and Field tag, the id is the one we use in css and name should
be the name of the field that we created in our database i.e. in the models/table
file.

we can use <label> tag beofre the <Field> tag to show its label.

You might also like