How to export multiple components in Reactjs


Usually we organize components React components in separate files. But for smaller components associated with component we are using need not be placed in operate file. In short it is possible to place multiple components in a single js file and export them.

 .....
  our component codes goes her

module.exports= {Post,Tags,Comments}

In the above fashion we can export the components and can import the components as follows

 const {Post,Tags,Comments} =from './components'

How to create ant row design for Reactjs


We are already learn how can utilize the antd for a Reactjs projects. Let’ quickly design a rows with columns ( a grid design) using the easy to use customize UI provided by Ant Design .

Go to Ant Row documentation , adjust the gutters and column count and click the copy code icon and past it where ever you need them.

Following ant design posts deserve good read

Ant layout for Reactjs apps


Ant Design is a UI Kit for developing beautiful web app and it is the second most popular one, it is just like Bootstrap we are familiar. In fact many apps have using multiple UI kits, there are plenty of UI kit available.

Install antd

Using Layouts we can create a skeleton structure of the app, which includes header, footer and content section. For using them in our React app, install the package using

npm i antd

Import Ant Design components

In our app.js we need to import the package extract the header,content,footer objects and also the css for beautify the objects as follows.

import { Layout} from "antd";
import "antd/dist/antd.css";
const { Header, Content, Footer } = Layout;

Create app layout

We have everything we needed, the Header,content,Footer components , Lets organize our app layout in app.js file of React app,

<Router>
<Layout className="layout" style={{ background: "##f759ab" }}>
      <Header>
        Your custom header components here
      </Header>
      <Content style={{ padding: "0 15px" }}>
      <Route path="/about" exact component={AboutUs} />
        You can place more routes/content here 

      </Content>
      <Footer style={{ textAlign: "center" }}>
        space for custom footer component
      </Footer>
    </Layout>
</Router>

That is the basics of the antd, explore more on he Ant for Reactjs

Following ant design posts deserve good read

How to render child components in Reactjs


Suppose we have components that called inside another in Reactjs , things can be messy. The parent component not render the child by default. Here is our code with two components.

export default class BackgroundDesign extends Component {
    render() {
        return (
            <div
            className="site-layout-content text-al"
            style={{ background: "#a8071a" }}
             
          />       
        )
    }
}

export default class SiteHeading extends Component {
  render() {
    return (
      <div className="site-layout" style={{ background: "#820014" }}>
        <span
          className="p-2"
          style={{ color: "whitesmoke", "font-size": "28px" }}
        >
          I am a Heading
        </span>
        
      </div>
    );
  }
}
 <BackgroundDesign>
            <SiteHeading/>
                It is a about  page.
            </BackgroundDesign>

In the above BackgroundDesign component we used Site Heading component which is not rendered successfully.

How to add element to mongoose object array in Nodejs


Mongoose array can set of objects basically a reference to other mongoose document placed in other document. Our task is to place a new element to MongoDB array of objects.

To add a new element we can use the $push command. In our Post example we had tags which need to added while updating the post.

Post.updateOne({_id:pst},
{
  $push:{'tags':ctag._id}
},
{  safe: true, upsert: true}
) 

$push will add the tag id to the tags object array

Alternatively we can afford the following method too. The difference is that the first one used inside a update command.

post.tags.push(stag)

How to auto create tables based on sequelize models


We had discussed how to auto create API using sequelize, on thing I missed is auto creation of tables.

Sequelize

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.

Auto create tables

Sequelize module has provided a function called sync in order to create tables based on the Sequelize models we created.

Place the call in the authenticate method of the Sequelize configuration as follows

const Sequelize=require('sequelize')
module.exports=new Sequelize('todo_collections','root','123',{
    host:'127.0.0.1',
    port:3306,
    dialect:'mysql',
    pool:{
        max:5,
        min:0,
        acquire:30000,
        idle:10000
    }
})

.......
.......

const db = require("./config/database");
db.authenticate()
  .then(() => {
      console.log("Database connected")
    db.sync()
    })
  .catch((e) => console.log("Error:" + e));
app.get("/", (req, res) => {
  res.send("Hello world");
});

We can use sync({force:true}) for drop the tables already created

You may like to read these sequelize posts too

How to resolve sequelize-JSON.parse error in Node


When I start with Sequelize ORM end up with the body-parser error. Usually we define body parser using app.use(bodyparser.json()), which globally declare parser functionality for all routes.

SyntaxError: Unexpected token in JSON at position 0
at JSON.parse ()
at createStrictSyntaxError (E:\NodeProjects\sequelize-api -mysql\node_modules\body-parser\lib\types\json.js:158:10)
at parse (E:\NodeProjects\sequelize-api -mysql\node_modules\body-parser\lib\types\json.js:83:15)
at E:\NodeProjects\sequelize-api -mysql\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (E:\NodeProjects\sequelize-api -mysql\node_modules\raw-body\index.js:224:16)
at done (E:\NodeProjects\sequelize-api -mysql\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (E:\NodeProjects\sequelize-api -mysql\node_modules\raw-body\index.js:273:7)
at IncomingMessage.emit (node:events:388:22)
at endReadableNT (node:internal/streams/readable:1305:12)
at processTicksAndRejections (node:internal/process/task_queues:80:21)

Here is where sequelize findAll() like functionality collides and the above error log will be populated

Solution

We can apply route specific parser to fix this mess. Let’s see how

Before the fix

For simplicity I have omitted some of the lines in index.js (Node project file). Before the fix our routes look like this

...
app.use(bodyParser.urlencoded({extended:false})) 
app.use(bodyParser.json())

app.post("/todo",  (req, res, next) => {
    const {item,description}=req.body
    Todo.create({item:item,description:description})
    .then((model) => {
      res.status(200).send(model);
      })
      .catch((e) => {
        res.status(400).send("Error:" + e);
      });
  });

app.get("/todo", (req, res, next) => {
  Todo.findAll()
    .then((model) => {
        res.json({
            error: false,
            data: model
        })
    })
    .catch(error => res.json({
        error: true,
        data: [],
        error: error
    }))
});


After the fix

After the removal of the global json parser it will look like this

...
app.use(bodyParser.urlencoded({extended:false})) 
 

app.post("/todo", bodyParser.json(), (req, res, next) => {
    const {item,description}=req.body
    Todo.create({item:item,description:description})
    .then((model) => {
      res.status(200).send(model);
      })
      .catch((e) => {
        res.status(400).send("Error:" + e);
      });
  });

app.get("/todo", (req, res, next) => {
  Todo.findAll()
    .then((model) => {
        res.json({
            error: false,
            data: model
        })
    })
    .catch(error => res.json({
        error: true,
        data: [],
        error: error
    }))
});


we have added the parser function of the bodyParser to Post routes only and the problem solved

Create REST-API using sequelize -MariaDB ORM in Nodejs


We had many posts on API and I am moving on sequelize ORM which allows us to perform CURD operation in REST manner or using Modals, just like we done with mongoose.

Sequelize

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.

MariaDB

MariaDB is a community-developed, commercially supported fork of the MySQL relational database management system, intended to remain free and open-source software under the GNU General Public License. The standard installation come with Heidi SQL GUI which help us create and manage database and schemas.

You can download and install it from the official website

Todo API

todos table in Heidi SQL

Our API is used to create the todos ,store in MariaDB , and perform all CURD operations using sequelize modal.

First we need to create the above table in your Maria. Now lets create a basic Nodejs project.

Continue reading Create REST-API using sequelize -MariaDB ORM in Nodejs

How to interact with input in Reactjs


With Browser route we can create beautiful responsive React app on the go. Most of the dynamic applications accepts some feed back from users. How do we get this done.

This will involve the following

  • Setting state for the each input element.
  • Attach it to the value property of the input.
  • Add a button event function and attach it to the render method.

Setting State

I have a one input text field and a button in the component.

import React, { Component } from "react"; 
 
class Comment extends Component {
  constructor(props) {
    super(props);    
    this.state = {      
    };
  }
  
  
  render() {
    return (
      <div className="form-group  m-2 p-2">
        <textarea
          placeholder="Comment here"
          class="form-control"          
          aria-describedby="inputSuccess5Status"
        />
        <button
          className="btn btn-primary m-1 p-2"        >
          Comment
        </button>         
      </div>
    );
  }
}

export default Comment;

In the above Comment component I have used bootstrap to beautify the form with one Text Area and button element. We need to create and attach a state for the Text Area in the constructor, also need to attach the new value with the state, whenever the user enter the comment. So we need to setState the comment in the on Change event handler.

  • Create state
  • Create event handler for on Change
  • attach them to the HTML tags
class Comment extends Component {
  constructor(props) {
    super(props);
    this.onChangeComment = this.onChangeComment.bind(this);
    this.onPostComment = this.onPostComment.bind(this);
     
    this.state = {
      comment: "",
    };
  }
  onChangeComment(e) {
    this.setState({ comment: e.target.value });
  }

  onPostComment(e) {
    try {
      
     console.log('Thank for using react form')
    } catch (error) {
      console.log(error);
    }
  }
  
  render() {
    return (
      <div className="form-group  m-2 p-2">
        <textarea
          placeholder="Comment here"
          class="form-control"
          value={this.state.comment}
          onChange={this.onChangeComment}
          aria-describedby="inputSuccess5Status"
        />
        <button
          className="btn btn-primary m-1 p-2"
          onClick={this.onPostComment}
        >
          Comment
        </button>
         <CommentCard  comments={this.props.comments}/>
      </div>
    );
  }
}

In the above code , created a state comment , event handlers for input and button and bind them in the constructor.

In the on Change event update the state so, each time the user update will change the state.

Finally attach the state and handlers to form elements ( button,Text Area).

Where did can I see the log(‘…’) result ?. well ,open your browser , ctrl+shift+I ( for developer tools) then go to console and you will see the message)

Following React posts deserve good read

How to populate multiple MongoDB objects on the same path in express-node


In Nodejs app we are using mongoose driver for MongoDB, a NoSql database with speed and accuracy. Mongo store data as series of JSON element call document and the collection of document is called a collection , same as table in DBMS.

According to the Mongoose doc Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s)

So we have the following Document , in which we want to populate user information . For simplicity I skipped some of the mongo

[
    { "tags": [
            "5fef1f5187a69346300003a8",
            "5fef1f5187a69346300003a9",
            "5fef1f5187a69346300003aa"
        ],
        "_id": "5fef1f5087a69346300003a7",
        "title": "Title post",
        "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
        "user": "5fe4ab1e69b8d525c44ec293",
        "createdAt": "2021-01-01T13:10:40.468Z",
        "updatedAt": "2021-01-03T02:37:55.982Z",
        "__v": 11
    }
]

The document contains a list of posts with user information etc within the Tag ( not listed) . So the posts is a list of objects which should populate and inside each post have a user and list of tags object as well. Our task is to primarily populate the user object and the tags list.

We can do this right now using the find method of modal class accompanied by the populate command as follows

The tags array and the user belong to the posts path , so we have to repeat the population ( one for user and other for tags)

	const tid = req.params['tid']
			Tag.findById(tid).populate({
				path: 'posts',
				populate: {
					path: 'tags'
				},
				populate: {
					path: 'user',
					select: 'name'
				}
			}).populate({
				path: 'posts',
				populate: {
					path: 'tags',
					select: 'tagName'
				}
			}).exec((err, post) => {
				if (err) return handleError(err)
				console.log('tagged posts are ' + post);
				return res.status(200).send(post.posts)


			})

Result

[
    {
       
        "tags": [
            {
                "_id": "5fef1f5187a69346300003a8",
                "tagName": "Test"
            },
            {
                "_id": "5fef1f5187a69346300003a9",
                "tagName": "VM"
            },
            {
                "_id": "5fef1f5187a69346300003aa",
                "tagName": "JS"
            }
        ],
        "_id": "5fef1f5087a69346300003a7",
        "title": "Title post",
        "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
        "user": {
            "_id": "5fe4ab1e69b8d525c44ec293",
            "name": "admin"
        },
        "createdAt": "2021-01-01T13:10:40.468Z",
        "updatedAt": "2021-01-03T02:37:55.982Z",
        "__v": 11
    }
]

In the above code we had used the populate inside another populate because the each posts had user element.

Following mongoose post also deserve a good read