Product Listing Creator: Showing Channel List

In the last post, I wrote about showing products list in my application. It was the most important functionality after ‘upload CSV’ functionality. The next most important functionality of my application is adding products to a channel list.

The problem that the Product Listing Creator solves is that it makes it easy to manage Product Listings on multiple channels. So, this makes it a very important functionality. However, it would not work without first uploading the products and viewing them. These were the first steps for using the application. The next step would be to add some of these products in different channel lists.

For this, I created a component with a route called Amazon List. I am starting with Amazon and it can then be expanded to other channels. This component is similar to MainList Component, except that it shows different data and has slightly different functionality. Create a new file called AmazonList.js and add this code in it:

import React, { Component } from 'react';
import { service } from './service';

class AmazonList extends Component {
  constructor () {
     super();
     this.state = {
       list: []
     }
  }

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

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

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

Then implement ‘getAmazonProducts’ in service.js:

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

Now on the server application, implement ‘/amazonlist’ API in the server.js file:

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

In database.js, implement ‘getAmazonList’ to fetch the list with ‘amazon’ flag as true:

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

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

      callback(data);
  }};
}

This implements Amazon List component. Also, add it as a route in index.js:

import AmazonList from './AmazonList';

..
<Router>
 ..
 <Route path="/amazonlist" component={AmazonList} />
</Router>
..

Now, add a link to this route in App.js for navigation:

..
<li><Link className="AppLink" to="/amazonlist">Amazon List</Link></li>
..

Now we can browse to Amazon List. Let’s add products to this list. The products will be added to list from the Main List. For this add a button corresponding to each row in MainList:

..
var button = (!product.amazon) ? <button className="ProductRowButton" onClick={() => this.addToAmazon(product._id)}>Add to Amazon</button> : '';
return (<div className = "ProductRow" key={product._id}>
        {spans}
        {button}
      </div>);
..

Now, implement ‘addToAmazon’:

addToAmazon (id) {
  service.addToAmazon(id, result => {
    var newList = this.state.list.map(product => {
      return product._id === id ? Object.assign({}, product, {amazon: true}) : Object.assign({}, product);
    });
    this.setState({list: newList});
  }, err => {
    console.log(err);
  });
} 

In service.js, add the new function to add a product to Amazon List:

var addToAmazon = function(id, callback, errorCallback) {
  fetch(API_URL + '/addtoamazon/' + id)
    .then(res => {
      callback(res);
    })
    .catch(err => {
      errorCallback(err);
    });
}

Now, implement ‘/addtoamazon’ in API. In server.js:

app.get('/addtoamazon/:id', function(req, res) {
  var id = ObjectID(req.params.id);
  database.addToAmazon(id, db, function() {
    res.send("Product add to amazon");
  }, function(err) {
    console.log(err);
  });
});

Now in database.js:

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

  collection.updateOne({_id: id}, {$set: {amazon: true}}, function (err, result) {
      if (err) {
        errorCallback(err);
        return;
      }

      callback(result);
  });
}

This implements the adding to Amazon List functionality. We can also use the same approach to remove a product from Amazon List. Just add a button in AmazonList with the label ‘Remove’ and implement the service and API for it, just like above. Only, it will set the ‘amazon’ flag to false, in database.js.

This completes the functionality for Showing, adding and removing products from the channel list.

This is the minimum viable product for managing product listings for multiple channels. In future, I can implement more channels, export functionality, custom fields for a channel, etc.