Product Listing Creator: Showing products list

In the last post, I wrote about upload CSV feature for Product Listing Creator. In this post, I am writing about the next most important feature that I implemented in the application. It is to show the list of products that have been uploaded.

The list of products will be shown on a different page than the main page of the application. It will have a URL like this: localhost:5000/mainpage. To implement these routes in the application, I am using react router. Let’s implement it first so that we can have multiple routes.

First install the react-router-dom NPM package, which is the web or browser version of react-router.
npm install --save react-router-dom

Before, starting to implement routes, there is one thing I need to fix. I am using my Main component inside the App component which has the header, etc. I want to the header to be there for every page that I create. This means that App and Main component should be separated so that App can be used for every route.

So, I removed ‘Main’ from the App component, I will implement it as a route.

To add routes to my application, lets import react router on index.js and start using it. In index.js file import BrowserRouter, Route modules. Also, import the Main component.

import { BrowserRouter as Router, Route } from 'react-router-dom';
import Main from './Main';

Now replace with the routing code:

<Router>
 <div>
  <App />
  <Route path="/" component={Main} />
 </div>
</Router>

This sets up routing for the application. Also, the path to main component(‘/’) should be exact path, otherwise other paths that start with ‘/’ will render their components below the Main component.

<Route exact path="/" component={Main} />

Now, let’s add a new component for showing product list. Create a new file called MainList.js and write this code;

import React, { Component } from 'react';

class MainList extends Component {
  
  constructor () {
    super();
    this.state = {
      list: [{title:'abc'}, {title: 'def'}]
    }
  }
  render () {
    var rows = this.state.list.map((product) => {
      return (<div className="ProductRow">
        row.title
      </div>);
    });

    return (<div className = "ProductList">
      {rows}
    </div>);
  }
}

export default MainList;

Now add a path to MainList in Routes in index.js:

import MainList from './MainList';

..

<Router>
 ..
 <Route path="/mainlist" component ={MainList} />
</Router>
..

This will open the Main list component on going to localhost:5000/mainlist, just below the App component(containing header).

Now to link to these routes, we need to add navigation in App.js on the right side in the header. In App.js, import Link module of react-router:

import { Link } from 'react-router-dom';

Then, in the render method add an unordered list of links to different routes:

..
<div className="AppLinks">
  <ul>
    <li><Link className="AppLink" to="/">Home</Link></li>
    <li><Link className="AppLink" to="/mainlist">Main List</Link></li>
  <ul>
</div>
..
</div>

Now that routes to both the pages are setup, let’s work on Main List page to show products uploaded with CSV.
In MainList.js, let’s write code to render the fields in CSV on the UI:

..
var rows = this.state.list.map((product) => {
      var spans = Object.keys(product).map((key) => {
        return <div key={product._id+key} className="ProductRowDetail">product[key]</div>
      });
      
      return (<div key={product._id} className="ProductRow">
        {spans}
      </div>);
    });
..

Now, we need to fetch the products from the database. For this create a method in service.js called getProducts:

var getProducts = function(callback, errorCallback) {
  fetch(API_URL + '/mainlist')
   .then(res => {
     res.json().then(data => {
       callback(data);
     });
   })
   .catch(err => {
     errorCallback(err);
   });
}

export const service = {
  ..
  getProducts: getproducts
}

Now make the call to service in MainList.js componentDidMount method, after importing the service:

import { service } from './service.js';

..
componentDidMount () {
  service.getProducts(data => {
    this.setState({list: data});
  }, (err) => {
    console.log(err);
  }
}

Let’s implement the API for ‘/mainlist’ for this to work. In the server application, in server.js, add this method:

app.get('/mainlist', function(req, res) {
  database.getProducts(db, function(data) {
    res.send(data);
  }, function(err) {
    console.log(err);
  })
});

Then in database.js, fetch data from the database:

var getProducts = function(db, callback, errorCallback) {
  var collection = db.collection('MainList');

  collection.find({}).toArray(function(err, data) {
      if (err) {
         errorCallback(err);
         return;
      }

      callback(data);
  });
}

module.exports = {
  ..
  getProducts: getProducts
}

This completes the implementation of showing Main List. I also made some UI changes to make it look good in MainList.css file. In next post, I will write about adding products to Amazon list from the Main list.