Fullstack CRUD application using Fastify, React, Redux & MongoDB Part-1

Fullstack CRUD application using Fastify, React, Redux & MongoDB Part-1Let’s create something interestingJatin KumarBlockedUnblockFollowFollowingMay 25Hi, there.

I hope that you are having a good time.

Now let’s make it even better.

In today’s tutorial we’ll be building a Fullstack Application using Fastify, React, Redux and MongoDB, which would support all CRUD functionalities.

The application that we are about to built is a simple menu app that lists all the menu items currently present in the database, In this application you would be able to create menu items, which could hold details like item-name and item-price.

You could also modify them or even delete them.

If you want see all the these features live in action, feel free to check out it’s completed version live here and play with it, till you are able to get a high level grasp of what you’ll be building throughout rest of this tutorial.

Final source code of the application is available here.

This tutorial would be a two part series, In it’s first installment we would be building static implementation of Web App using React and Redux, And in our second installment we’ll be wrapping up with app by adding a Fastify.

js backend and MongoDB database.

 Seeing the popularity of React, Redux, Fastify and MongoDB.

It would be pretty interesting to find out how they all aces work in conjunction.

So let’s without wasting any time dive right in!Things to know before getting startedThis tutorial is for anyone who is interested in learning new things and has some basic knowledge of React, Redux, MongoDB and RestAPIs in general.

React developers who haven’t coded for a while yet, can also follow along in order to get back in their old form.

Though I would be giving my best to explain each piece of code as we build the app.

But it would be of great help if you have you have some basic understanding of core concepts already.

In addition we’ll be using quite some ES6 syntax, so it would be pretty good if you know some of them already like arrow functions and spread operator.

So, Enough of talking, let’s get started!Project SetupBefore moving on please ensure that you have node.

js installed in your machine, If not then please get it installed before heading forward.

You can install node.

js from it’s official site https://nodejs.

orgAfter getting node.

js installed, Now let’s start by initializing our project by executing commands shown below in your terminal.

mkdir fastify-react-crudcd fastify-react-crudtouch .

babelrcmkdir server mkdir src && cd srctouch index.

html index.

js menu.

js menu.

cssmkdir components && cd componentstouch form.

js menuItem.

jscd .

mkdir redux/actionsmkdir redux/reducersmkdir redux/storecd redux/actions && touch actions.

js && cd .

/.

/cd redux/reducers && touch reducer.

js && cd .

/.

/cd redux/store && touch store.

js cd .

/.

/.

/.

/Alright!, So that was a lot of setup code.

But we were going to do it anyway, so I preferred to keep them stacked together so that we have least chances of getting differences in our file structure.

 Note : In case you are on windows and are using windows cmd, Please shift to gitbash because concatenation of commands using && operator doesn’t goes well with traditional windows cmd.

 Now let’s install some npm packages to get going.

We’ll start with building our View Layer.

So let’s install some packages required to build our React frontend.

Note : We’ll be using Parcel Bundler to develop our react frontend.

In case you are unaware of parcel, then you should know that in a nutshell it’s nothing more than application bundler similar to webpack.

We’ll be using parcel as it’s just comparatively easy to setup and work with.

Now if you had executed the shell commands right, you must already be in the project root.

But in case for any reason you are not, please navigate to your project root and execute commands shown below.

npm init -ynpm i –save react react-dom redux react-redux redux-thunknpm i –save-dev parcel-bundler npm i –save-dev @babel/plugin-proposal-class-propertiesopen package.

json and add dev script shown below"scripts": { "dev": "parcel src/index.

html"}Now, open .

babelrc and copy paste the line show below.

So that we can use arrow functions in our React components.

{ "plugins": [ "@babel/plugin-proposal-class-properties" ]}After having all the commands executed successfully, you must be having your project file structure quite similar to like this.

fastify-react-crud|–node_modules // contains node modules|–server // will contain server related files|–src // will contain cleint side related files|—-components // will contain child components of menu.

js|——form.

js // form component for Addition & Updation|——menuItem.

js // component to display menu item|—-redux // contains redux related files & folders|——actions |——–actions.

js // contains redux actions|——reducers|——–reducer.

js // contains redux reducer|——store|——–store.

js // here we create redux store|—-menu.

css // will contain css code |—-menu.

js // will contain react code|—-index.

html // will contain html template|—-index.

js // will contain react code|–package.

json|–.

babelrc // babel plugin configLet’s start building our React-Redux Frontend!Quick Structure AnalysisIf you have seen the demo already, then the image shown below might seem quite familiar to you.

If you’ve not visited the demo link yet, I’ll highly recommend you to visit.

Because it would give you a broader picture of project that we are about to make.

Application component structureNow after you have seen demo, You can easily interpret by seeing the above image, that our App consists of <Menu/> component, which wraps major functionality of our application.

Later as we start coding you’ll get to know that it’s also kinda powerhouse of our application because this is the only component in our application which would be communicating with the redux store.

As we go one layer deep <MenuItem/> component comes to our notice, It displays the data in really nice formatted fashion and besides that it also provides us with the ability to Modify and delete data using their respective buttons.

When you click on the Edit button or Create New Item Button, you would unlock another component which is <Form/> component.

It is very important component because this single component is used in two different situations i.

e.

Addition of Items and Modification of items.

It also has his own set of functional buttons using which we can either submit our data or cancel the request which can be either of addition or updation.

So, Now that you have understood what individual component actually does or at least what it’s supposed to do.

I think we are ready to get our hand’s dirty with some code.

Let’s start by Redux first, So that later on when we build components we know what’s happening under the hood and how is it happeningEnter Redux !Okay, Now In case you are confused about some basics of redux, like what does what or what is the relation ship between them, then the image shown below must clear some mist around it.

Step 1: Lets start by defining some actions, Open actions.

js and copy the code shown below.

Now in case you are wondering what an action is ?.then you should know that in a nutshell it’s job is only to trigger some piece of code defined in reducer, which would in turn update the store depending on type of action and that’s it, nothing more!.You might have already observed a pattern from code above, that an action always returns an object.

The object that’s to be sent by action essentially expects two properties namely type and payload.

Of both type is mandatory to be specified no matter what.

for eg.

readItem action doesn’t require a payload but would not work without type property.

Now in case you are wondering what a payload actually is?.then Basically it’s just a piece of data that’s sent from our view layer to reducer for a variety of purposes, for eg.

Create, Update, Delete.

Now coming back to our actions file, here we havecreateItem : It accepts item to be created as it’s payload and it’s dispatched when we want to add a new itemupdateItem : It also accepts item to be updated as it’s payload and it’s dispatched when we need to update any item.

deleteItem : It accepts id of the element to be removed as it’s payload and it’s dispatched when we need to delete any item.

readItems : It is dispatched to read items from redux-store.

It doesn’t has any payload yet.

But in next part of tutorial it would play a important role, as it would be used to fetch items from the database.

Now I think actions is all clear, let’s try to clear our next hurdle i.

e.

reducersStep 2: Open reducer.

js and copy the code shown below.

So, that’s what our reducer looks like, like all ordinary reducers we haveAn initial state for store represented by initialState variablewe have reducer function which expects two arguments namely, state and action.

Whenever we dispatch an action it sends an object to reducer (You should be nodding right now).

That object has a mandatory property type .

And that’s mandatory because we require type in order to identify an action distinctly from others, you can think of it as an id for the action.

Depending on type of action, Our reducer decides whether to Create item, Read items , Modify item or Delete item.

But whatever it decides it has do it by not mutating the original state.

Because in case you mutate state, store’s state may get updated but react will not detect it and you would not be able to witness changes in your react app.

FYI 90% of errors in any redux app happens due to mutated state.

So, always be careful to not accidentally mutate the state while working with redux app.

In order to work with immutability we need to create copy of the original state.

There are generally 2–3 ways to do it.

I have used the latest and easiest of all, which is by using spread operator.

If it’s new to you, feel free to visit docs here.

I can not discuss more about immutability right now, because it’s a topic which demands it’s own tutorial, so we’ll leave it here only.

For now you only need to know that [.

array] is a copy of and array and {.

object} is a copy of an object.

Now, Let’s get back to our reducer.

In our state we have a menuItems property which is of type array.

On action type CREATE we add an item to menuItems array and send a new state back to our view.

In case of action type READ we simple return the stored state.

In case of UPDATE we map over the copy of the menuItems and send the state after updating content of the desired item.

One important thing to notice here is that, here we don’t need to make a copy of menuItems because when we use map to iterate of elements, a new copy of array is automatically created and returned.

But I have done it just for double safety (Ya that’s the fear of mutating the state xD).

Now in case of DELETE we simple return the filtered array by ignoring the item which has id similar to what was passed in payload.

That’s It for our reducer.

I Hope, that you were able to understand the reducer.

Let’s bind up with redux section by creating store.

Step 3: Open store.

js and copy the code shown below.

So, now that’s the shortest piece of code in the whole project.

It just imports reducer and createStore utility, then we create store and export it.

We’ll be importing it in index.

js later in this tutorial.

So that’s all for the redux but to see the functionality we build, we require View Layer so let’s get this one done quickly using React!Let’s create something presentable!Step 1: let’s start with index.

html, Open index.

html and copy the code shown below.

This code above is all self explanatory we just have a link tag for fontawesome icons, which we use in buttons.

It’s completely optional you can write texts in buttons instead if you desire.

Besides link, we have also a script tag to import index.

js.

Step 2: Now, navigate to index.

js and copy the code shown below.

This is outermost wrapper component of our react app, It was skipped during structure discussion.

Actually It doesn’t do much besides making store available to our Menu component.

Other than that rest must be self explanatory.

Now next up we’ll be building <Form/> component, It would going to be quite interesting at least as compared to first two steps xD.

Step 3: Now, Open form.

js and copy the code shown below.

So that’s what our <Form/> component looks like, If you read the code once, You would realize that it’s nothing more than a ordinary form having two input fields and two buttons which are used to submit and close form.

When we press submit button handleSubmit function get’s invoked and on pressing cancel button handleCancel function get invoked.

They both make further calls to respective functions in parent component.

For time being just forget about these parent component’s functions.

Just remember that handleSubmit sends the form data to parent component and handleCancel closes form and that’s it.

We’ll learn about these parent component’s functions in detail later, till time you should just know that what they do.

All right now let’s talk about it’s state, you can see that we are not taking it empty by default rather we check for props and initialize state with values passed in props in case they were.

That’s because our <Form/> component is multipurpose component, It is used as Create Item Form as well as Edit Item Form, so when it’s used as Create Item Form no props are passed so state remains empty and user see’s empty fields as they should.

But when it’s used as Edit Item Form, props are passed and input fields get’s filled with values passed in props thus user is able to see the value that he/she is about to edit.

Now next up is our handleChange function, It basically changes state of name and price whenever values in input fields are changed.

It’s able to do so because it’s attached to both of the input field’s onChange event and get’s triggered when ever value in input is changed.

Inside function we use object destructuring to extract name and price from state.

and change the relevant state property which is decided by the value of e.

target.

name (It only works when input field has name attribute).

So that was our <Form/> component for you, next up we’ll write code for menuItem.

jsStep 4: Now let’s build<MenuItem/> .

You may copy code shown below.

Now It may have few more lines of code as compared to <Form/> component discussed above a while ago.

But it is quite simpler compared to it in terms of functionality.

Similar to <Form/> we also have state which we initialize with the values passed by parent component.

But in this scenario we opt for different technique to do it rather than initializing directly in constructor which is sometimes not recommended though.

In <MenuItem/> we use componentDidMount lifecycle method to update state with the props whenever component mounts.

Apart from name, price we also have openEditForm property in our state which is component specific and it has nothing to do with it’s parent component.

openEditForm is basically used to toggle Edit Item Form.

It doesn’t has any more application.

Similar to <Form/> It also has a pair of buttons, But their functionality is quite different.

Two Buttons are Edit and Delete.

When Edit button is pressed handleEditClick function is invoked which sets openEditForm to true which in turn opens the form to edit items and whereas when Delete button is pressed handleDelete is invoked.

In addtion there is also handleUpdate function which get’s invoked whenever user submits after editing i.

e.

sends update request.

Both handleDelete & handleUpdate make further calls to functions defined in <Menu/> component in order to actually delete and update item from storage.

We will look at these functions in menu.

js next up in great detail.

So that’all for <MenuItem/>, let’s see up next what <Menu/> has us to offer.

Note : when handleUpadte is invoked it also sets openEditForm back to false which toggles form and let’s us see the saved content of that item.

Step 5: Now let’s open menu.

js and copy the code shown below.

Alright Now that’s quite lot of code compare to the first 2 entries.

But that’s just because it handles a lot of functionality.

All our create, update, deletion in store are initiated from this component only.

I have commented every useful block of code and I am confident that if you go through it once own your own, you would get a good percentage of code in your first attempt only.

Because it’s just lengthy otherwise it’s easy to understand.

So give it a try, go through whole code once and return here, I promise it would prove beneficial and you would thank me after this.

Alright, So how did it go?.I am positive that you would have been able to get at least some piece of code if not all.

Well that’s Okay.

Also you should be proud of yourself even if you got even some piece of it, because it’s never easy to read someone else’s code xD.

Alright so now let’s get serious and get the job done.

Now I’ll be going through the above code, follow along and Let’s check how much of it you got right!.Well, by merely seeing the imports one can recognize that this component communicates with redux store, uses <MenuItem/> and <Form/> components (we’ve discussed them above already) , imports css and we also import some actions that we created in action.

js a while back.

 Now let’s talk about it’s internal state.

Well, It’s internal state doesn’t has much to offer except an openAddForm property whose job in a nutshell is just to toggle display of create item form, well that’s an expected behaviour when your app uses redux as then our major state resides in our redux store.

Next we have a fair amount of handlers here, Remember when I said that Menu.

js is powerhouse of our application.

You can say that these handlers our the ones who provides it with power.

First handler to encounter is handleAddClick , Now it’s very similar to handleEditClick discussed while creating <MenuItem/> component.

It’s also used to setopenAddForm to true which in turn toggles the Add Form Component.

Now next up is handleAddItem function which is used to add item to redux store.

It receives data when the Add Form (same <Form/> component used in MenuItem, but rendered with empty fields) is submitted.

It checks for falsy values and in case it founds one it replaces them with default value.

After verification of values createItem action is invoked with new item as argument and rest is all taken care by redux.

Now next event handler is handleDeleteItem which is used to remove item from redux store.

It is invoked by <MenuItem/> with id of item to be deleted.

In turn handleDeleteItem in turn invokes deleteItem action with id of item to be deleted as argument.

Next event handler that we come across is handleUpdateItem which is used to update item in redux store.

Like in previous handler, It’s also invoked by <MenuItem/> but with full item object not just id.

in turn handleUpdateItem dispatches updateItem action with item object as argument.

Now last event handler to encounter is handleCancel which is quite similar to one defined in <MenuItem/> , so you already know what it does.

Majority of code is commented so rest of code may not require any additional explanation.

Other than that we have defined mapStateToProps function in order to subscribe to redux store state updates.

Here we subscribed for updates for menuItems property.

As a last step we connect our <Menu/> component to redux store using connect, After connecting to store we get menuItems as prop to <Menu/> component.

So that’ all folks for the menu.

js.

Now we just need to run it and see what we built so far.

Hey don’t you think, we are forgetting something ?.Yes, we are.

Our menu.

css is still empty.

And if you run your app now, It could well be a nightmare.

If you want you can use the css that I wrote for this app and not waste time on writing your own.

You can download css from here.

Now navigate to terminal and execute npm run dev and navigate to http://localhost:1234/ and you might be seeing the application up and running very similar to shown below.

What’s next ?Alright folks!.We’re done with our first leg of the two part tutorial.

Till now we’ve successfully created a fully functional React Redux CRUD application.

But it still has one problem that needs to be fixed,which is that the changes are not persistent and it disappears whenever the app is reloaded.

So, In next part we’ll be making changes persistent, for which we’ll be using fastify and MongoDB Atlas.

It would be quite interesting to see how these all techs work in conjunction.

So let’s meet in it’s second part where we’ll add Fastify and MongoDB Atlas to our current application.

If you enjoyed this post, I’d be very grateful if you’d help it spread by sharing it to a friend, via Twitter or Facebook.

And as always please let me know in comments how did you find this tutorial.

Thank you!.

.

. More details

Leave a Reply