Thursday 20 April 2017

node.js server is hit multiple times into async function in React

I'm working with React, MongoDB, node.js and Express and this is my situation:

I have this piece of code inside my component:

   renderWishlist(){
      var quantity;
      var itemID;
      var tmp;
      var myData = this.props.currentCart;
      // console.log(myData.length) returns 3
      for (var k=0; k<myData.length; k++){
        tmp = myData[k];
        quantity = tmp.quantity;
        itemID = tmp.itemID;
        this.props.fetchBook(itemID).then(function(book){
          console.log("book: "+JSON.stringify(book));
        });
      }
    }

myData is an object which holds a bunch of books info. As you can see from my code above I'm iterating through all these books, retrieving the ID of the book and the available quantity, then I try to get other information (price, pages, etc...) for that particular book from another collection inside the same MongoDB database. Once this piece of code is running I keep getting multiple logs like this inside chrome console:

book: {"type":"fetch_book","payload":{"data":{"_id":"58f6138d734d1d3b89bbbe31","chef":"Heinz von Holzen","title":"A New Approach to Indonesian Cooking","pages":"132","price":23,"image":"IndonesianCooking"},"status":200,"statusText":"OK","headers":{"content-type":"application/json; charset=utf-8","cache-control":"no-cache"},"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json, text/plain, */*"},"method":"get","url":"http://localhost:3001/books/58f6138d734d1d3b89bbbe31"},"request":{}}}

Which retrieves correctly the book but it seems to hit the server multiple times for the same book and I don't know why.

For completeness this is fetchBook action creator:

export function fetchBook(id){
  const request = axios.get('http://localhost:3001/books/'+id);
    return {
        type: FETCH_BOOK,
        payload: request
    };
}

The reducer:

import {FETCH_BOOKS, FETCH_BOOK,FETCH_WISHLIST} from '../actions/types';

const INITIAL_STATE = { myBooks:[], currentCart:[], currentBook:[] };

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
    case FETCH_BOOKS:
      return { ...state, myBooks:action.payload };
    case FETCH_BOOK:
      return { ...state, currentBook:action.payload };
    case FETCH_WISHLIST:
    console.log("ciccio: "+JSON.stringify(action.payload));
      return { ...state, currentCart: action.payload };
    default:
      return state;
  }
}

My node.js server call:

router.get('/books/:id', function(req, res, next){
     Book.findById({_id:req.params.id}).then(function(book){
        res.send(book);
      }).catch(next);
   });

Why the server is hit multiple times? If I have, let's say 3 books inside myData, I'd expect the server to be hit only 3 times.

Another question I have is: How can I make the for loop to wait for fetchBook action to finish before going on iterating the next myData item?



via splunk

No comments:

Post a Comment