I am full stack web developer building web and mobile app for businesses.



I am a freelance and full-stack developer with a passion for building software solutions.


I love writing about the things that I have learned.

Email me

if you think we should be working together on interesting projects.


I create youtube videos, covering how I work and thinks as a full-stack developer

Watch on youtube.


Lets you sync your time with anyone’s time in the world with a click of a button.https://timexonesyncer.tech/



Record and Share your awesome voice on the fly with your friends and rest of the world. SingAndShare makes it easy to record an audio file or choose already recorded file to upload it to our server and allow users to share them to social media like facebook,twitter etc.https://sing-share.vercel.app/


Strapi content-type for simple portfolio and blog application

Last updated Dec 22, 2021


This is the second blog post on the series of a blogposts I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at [myportfolio](https://myportfolioandblog.vercel.app/) If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series. In the last blog post we created bare-bones setup for strapi and nextjs with tailwindcss if you have not read the first blog post then go ahead https://dev.to/bishaln/strapinextjs-and-tailwind-setup-50nk In this blog post, we're going to look at the strapi's content-type and build our content-type for our portfolio/blog application. # Content-type builder It is a core plugin of strapi that allows us to manage the content-types and content-type defines the type of data that we want to use in our application. There are a few terms that we need to be aware of before going forward with this * Collection type - It is a content-type that can manage entries of the same content-type * Single type - It is also a content-type that can only manage single entry * Components are a data structure that can be used in multiple collection types and single types. We've some regular fields that we can use in our content-type most of them are obvious so I will not bother explaining them * text-field * rich-text * number * date * boolean * relation - used to establish relationships with another content-type * email * password * enumeration * media * json * uid Now that we have a decent understanding of strapi's content-type let's create the content type that we will need for our app. We'll have in total 4 content types as * Homepage - This is a single type that will contain all the data for our portfolio landing page * Writer - This is a collection type that will contain info about the writer of the blog posts * Post - This is a collection type * Playlist - This is a collection type that will contain posts related to the playlist Let's create them inside the strapi admin for that Inside your strapi project run ``` yarn develop or npm run develop ``` Go to http://localhost:1337/admin and click the content-type builder in the plugins list # Homepage First let's create the homepage single type click on create a single type link and give it a name Homepage and Before adding any components or fields to our homepage single type I want you to visit the final app here https://myportfolioandblog.vercel.app/ If you see it carefully then it has 5 distinct sections * hero * about * projects * recent blogs * contacts we'll create 4 components named hero, about, projects, and contacts. We will not create a recent blogs component for now; Inside the homepage single type click on add another field and select the component. Create a new component with the name Hero and a category with hero. Click on the configure selecting the single component. Now let's add some fields to this component title - text field navlinks - text field profile - media After adding this field the homepage single type looks something like this ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28hxkpum4x3f86dxbc7t.png) Now let's add another component About follow the similar process and add these fields to the About component * work- text field select the long text radio * blogs- same as work * watch- same as work * email- same as work Add another component Project follow the similar process but this time select the repeatable type instead of a single type so that we can add multiple projects and add these fields to the Project component * title - text field for short text * description - text field for long text * url - text field for short text * image - media * bg - media * tools - text field for short text Finally, let's add the Contact component follow the similar process this time make it a single type, and add these fields. * email - text field for short text * insta - same as email * linkedin - same as email * twitter - same as email * youtube - same as email * title - same as email Make sure to save the homepage. After all that we can now add real data to the homepage single type. ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvt9tfhcsyiw8t2l1lnr.png) Go ahead and add some dummy data to the homepage if you want to Now we can focus on the other three collection types # Writer Go to content type builder and select create a new collection type and name it writer Add these fields to the writer content type and save it * name - text field for short text * avatar - media for avatar * bio - text field for long text # Post Once again let's create another content type with the following fields and save it * title - text field for short text * description - rich text * topics - text field for short text * slug - text field for short text make it unique to do that go to advanced tab and select unique * writer - relation select writer content type and post has and belongs to one user # Playlist Once again let's create another content type with the following fields and save it * title - text field for short text * description - text field for long text * slug - text field for short text make it unique to do that go to advanced tab and select unique * posts - relation select posts content type and playlist has many posts we have to add some relation fields to posts and writers first let's add a playlist relation to posts as post has one playlist save it. Inside the writer, content-type add posts relation as a writer has many posts and save it Now go ahead and some dummy data to all the content-types so that we can query them; Before querying them we have to make all the content-types find and findone functions publicly available to do that goto settings -> user permission roles -> public and check all the find and findones So now, to test lets query for all the data that you will need for the landing page; This query fetches all the data required for the landing page; cool isn't it? ``` query { homepage { Hero { title navlinks profile {url} } About { work blogs watch email } Project { title description tools image {url} url bg {url} } Contact { email insta linkedin twitter youtube title } } } ``` **So this is it for the content-type in strapi and we have added required content-types for our project. In the next blog post we will setup nextjs to make graphql requests and generate some type information from our queries. If you had any problem following along then let me know in the discussions**

Read Blog

Strapi,Nextjs and Tailwind setup

Last updated Dec 22, 2021


This is the first blog post on the series of a blog posts I will be posting about strapi,nextjs, and tailwind. We will be recreating my portfolio/blogpost website and along the way, we'll learn the fundamentals of strapi,nextjs and tailwind. You can check my [myportfolio](https://myportfolioandblog.vercel.app/) If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series. I am assuming that you have nodejs installed in your machine and I will be using yarn instead of npm you don't have to use yarn if you want then make sure to install yarn globally as ``` npm i -g yarn ``` # Strapi It is a headless content management system. Headless means it only serves data and not HTML and CSS. This is very powerful since we will just be getting the data that we care about and we can write the UI logic to display it nicely. We can use the same API endpoint in all the platforms to request the data be it web, mobile, or desktop. It comes with an admin UI that helps us to manage the content easily. Enough talk now let's see it in action; To create a brand new strapi app run ``` yarn create strapi-app nameofyourapp or npx create-strapi-app my-project ``` It will ask for the installation type select custom and no for template choose sqlite as the development database we'll use postgres in production. ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qztxikwi9cn4418ufcz.png) It will create a bunch of files for us we don't have to worry about any of the files created for now; So go ahead and run ``` yarn develop ``` It will first build the admin UI and spin up the server by default at http://localhost:1337 Now go ahead and open that link in a browser and for the first time, it will ask you for your credentials that we will use to login to the admin. After all that we should see an admin interface; In strapi we first create the content-type think of it is a data structure or table schema. Now let's create a simple content-type say an Author with username, bio and image. Go to the content-types builder and click on create new collection type and Name your collection type Author and add some fields to it. Hit the save button it will restart the server and add Author as your new collection type alongside the users which is the default collection type used for authentication purposes. Now let's add some dummy author data so that we can query them with an HTTP request to do that go to the author collection data and click the add new authors button. Fill in the data save it and publish it then we should be able to see the newly added author in the author's collection type. ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hkxr0an9b2u57jvxjbr.png) To get this data first we have to make this content publicly available to do that let's go to settings -> roles -> public and check the find and findone permissions and hit save. Now let's make a simple get request to http://localhost:1337/authors you should get something like this ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zo10p2whqf40cwo1sdwr.png) Strapi by default processes the image that we upload to the media library but we can change the setting, for now, let's keep things simple. For this project, I want to make use of graphql instead of rest. If you have never made use of graphql then don't worry it is very simple. It provides several advantages that you can look up on the internet, for now, let's install a strapi plugin that will allow us to make graphql requests to our strapi server. Go ahead and run; ``` yarn strapi install graphql or npm run strapi install graphql ``` After successful installation, we should be able to open up graphql playground at http://localhost:1337/graphql In graphql for get request we use query and for others mutation. Let's write a simple query to get all the authors. ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6vzcaanfw8bmiqmenov.png) ``` query { authors { id created_at username bio avatar { url } } } ``` We'll talk more about the strapi content-types and relation in another blog post for now let's focus on setting up Nextjs and Tailwind. # Nextjs It is a react framework that makes server-side rendering(SSR) and static site generation(SSG) super simple. In a normal create react app everything is computed client-side the user browser which is not good for performance as well as SEO. So we're going to make use of static site generation since the portfolio and blog site does not change that much. **The difference between SSR and SSG is that in SSG nextjs pulls all the data during the build process and creates all pages that you have. When someone requests to access your page they will be served the pages which were built during the build process and without making any backend calls. This improves the performance of your website as well as decreases the load to your backend server whereas in SSR nextjs makes requests to your backend server for every request from the clients creates the page on the server and then serves it to the client.** Let's setup nextjs with typescript ``` yarn create next-app --typescript or npx create-next-app@latest --typescript ``` ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drhp5ts30u8jh9sksc67.png) This will install all the dependencies and setup a simple page ``` yarn dev or npm run dev ``` This starts the next server in dev goto http://localhost:3000 # Tailwindcss It is a utility-first CSS framework that makes building UI simple and faster. Now let's add tailwindcss into the mix ``` yarn add -D tailwindcss@latest postcss@latest autoprefixer@latest or npm install -D tailwindcss@latest postcss@latest autoprefixer@latest ``` ``` npx tailwindcss init -p ``` Add this code snippet to the global CSS file ``` /* ./styles/globals.css */ @tailwind base; @tailwind components; @tailwind utilities; ``` If you are using vs code then you can install the tailwindcss extension that will give you cool autocompletion so that you don't have to remember the class names; Now let's remove all the markup from the index.tsx file and test simple class from tailwind to make the text bold and italic; ``` import type { NextPage } from 'next'; const Home: NextPage = () => { return ( <div> <p className='font-bold italic'>This is tailwindcss</p> </div> ); }; export default Home; ``` ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r57yla7pvjitf6ryq52m.png) **That is it for this blog post in the coming blog post we will discuss more about strapi content-types and add all the necessary content types for the portfolio/blog page Till then stay tuned if you have any questions about the current setup the let me know in the discussions**

Creating a CRUD Rest API using Nestjs

Last updated Dec 22, 2021


**Nestjs** is a nodejs framework that comes with lots of features out of the box unlike others such as expressjs, fastify which are minimal. Nestjs makes use of typescript by default which gives type safety to the project. Thus, keeping it safe from type errors which are quite common with javascript. *In this tutorial*, we are going to create a simple application that will help us create, read, update and delete notes about a topic. [Complete Project Github Repo](https://github.com/BishalN/CRUD-REST_API) First thing first make sure you have installed nodejs into your machine. `node -v` if it gives back some version number then we are good to go otherwise make sure you download and install nodejs from here [nodejs download](https://nodejs.org/en/download/) Now lets install nest cli; ``` npm i -g @nestjs/cli or yarn global add @nestjs/cli ``` Let's create a brand new project using nest cli and I will name my project mynotes. ``` nest new mynotes ``` This will create mynotes folder and a bunch of files that will get us up in running with nestjs. The main.ts file inside the src directory contains the main logic to start the nest application. Nestjs under the hood makes use of expressjs for HTTP implementation by default so we see expressjs like syntax to start the application. Before going through other files there are some term some terms that we need to know about nestjs; * **Module** In nest we divide our project into several modules and these modules can be imported by other modules in the same project. It is also used to register imports, **controllers** and **providers** * **Controllers** It is the actual route handlers * **Services** It contains the actual business logic that will be executed on the controllers * **Repository** It is used to define the data stores e.g Database entity i.e table Now we know the basic terminologies, Let's go through all the other files created for us * **app.module.ts** this file registers all the controllers and providers that are available in this module * **app.controllers.ts** this file has an actual *Get* route handler that returns hello world using the app service * **app.services.ts** is injectable meaning we can use dependency injection that is how we are making use of getHello function on our *app.controllers.ts* file. * **app.controller.spec.ts** is a test file where we can write a unit test. For this tutorial, we will only use the **app.module.ts**, **app.controller.ts**, and **main.ts** files. we will not make use of any other files so we can delete them. ![Folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fvszrsfc50q4o3abbit.PNG) Update the code in **app.module.ts** and **app.service.ts** to; ``` //app.module.ts import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; @Module({ imports: [], controllers: [AppController], }) export class AppModule {} //app.controller.ts import { Controller, Get } from '@nestjs/common'; @Controller() export class AppController { @Get() getHello(): string { return 'hello world'; } } ``` Now let's create the **POST** endpoint to create the new notes with topic and description as a string for that we can use *@POST* and *@BODY* decorator from the *@nest/common* ``` import { Body, Controller, Get, Post } from '@nestjs/common'; type note = { topic: string; description: string; id: number; }; @Controller() export class AppController { notes: note[] = []; @Post() createnote(@Body() { description, topic }: note) { const randomId = Math.floor(Math.random() * 999); const note = { description, topic, id: randomId }; this.notes.push(note); return note; } } ``` This will accept the post request at the root route and create a note and append it to the array. It returns the post created. Now let's create the **GET** endpoint that will return all the notes created and another that will return the note by id. ``` @Get() getAllnote(): note[] { return this.notes; } @Get('/:id') getNoteById(@Param('id') id: number): note { const noteIndex = this.notes.findIndex((note) => note.id === Number(id)); return this.notes[noteIndex]; } ``` Let's add the update functionality using a **PUT** endpoint ``` @Put('/:id') updatenote(@Param('id') id: number, @Body() newNote: Partial<note>): note { const noteIndex = this.notes.findIndex((note) => note.id === Number(id)); this.notes[noteIndex] = { ...this.notes[noteIndex], ...newNote }; return this.notes[noteIndex]; } ``` Finally, Let's implement the **DELETE** method ``` @Delete('/:id') deletenote(@Param('id') id: number): boolean { const noteIndex = this.notes.findIndex((note) => note.id === Number(id)); if (noteIndex === -1) return false; delete this.notes[noteIndex]; return true; } ``` We used the POST method to create the new note, the GET method to get notes, the PUT method to update the note, and the Delete method to delete the notes. So, that is it about this CRUD tutorial.

More posts

Stay In Touch

Images byMarek Piwnicki &Pixabay