3

I'm recieiving the error below while tring to run my react redux app.

It cannot find the basket api.

I can add more files if needed but I'll add the ones that I think are sufficient for this question.

I also am recieving "A no default engine was specified" when trying to navigate to my /basket page. I will inslude this too.

When I run the app>>

GET http://www.localhost:3000/api/basket 404 (Not Found)
dispatchXhrRequest @ bundle.js:17637
xhrAdapter @ bundle.js:17471
dispatchRequest @ bundle.js:40197
Promise resolved (async)
request @ bundle.js:39674
Axios.(anonymous function) @ bundle.js:39684
wrap @ bundle.js:17450
(anonymous) @ bundle.js:11273
(anonymous) @ bundle.js:36221
(anonymous) @ bundle.js:35887
componentDidMount @ bundle.js:21837
(anonymous) @ bundle.js:30139
measureLifeCyclePerf @ bundle.js:29949
(anonymous) @ bundle.js:30138
notifyAll @ bundle.js:13509
close @ bundle.js:32099
closeAll @ bundle.js:6749
perform @ bundle.js:6696
batchedMountComponentIntoNode @ bundle.js:15237
perform @ bundle.js:6683
batchedUpdates @ bundle.js:31765
batchedUpdates @ bundle.js:2529
_renderNewRootComponent @ bundle.js:15431
_renderSubtreeIntoContainer @ bundle.js:15512
render @ bundle.js:15533
(anonymous) @ bundle.js:22170
__webpack_require__ @ bundle.js:20
module.exports @ bundle.js:63
(anonymous) @ bundle.js:66
bundle.js:36239  action GET_BASKET_DECLINED @ 13:21:53.185

When I try to access my /basket

Error: No default engine was specified and no extension was provided.
    at new View (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\view.js:61:11)
    at EventEmitter.render (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\application.js:570:12)
    at ServerResponse.render (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\response.js:971:7)
    at C:\Users\Cmac\Documents\prj400r\dealstore\app.js:88:7
    at Layer.handle_error (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\layer.js:71:5)
    at trim_prefix (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:315:13)
    at C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:275:10)
    at C:\Users\Cmac\Documents\prj400r\dealstore\app.js:77:3
    at Layer.handle [as handle_request] (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\express\lib\router\index.js:275:10)
    at SendStream.error (C:\Users\Cmac\Documents\prj400r\dealstore\node_modules\serve-static\index.js:121:7)

My basket.js file

"use strict"

// NECCESSARY IMPORTS
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

// OTHER COMPONENTS IMPORTS
import {deleteBasketItem, updateBasket, getBasket} from '../../actions/basketActions';

// STYLING IMPORTS
import {Panel, Col, Row, Well, Button, ButtonGroup, Label, Modal} from 'react-bootstrap';





class Basket extends React.Component{
  componentDidMount(){
    this.props.getBasket();
  }
  // DELETE
  onDel(_id){
    const currentDealToDelete = this.props.basket;

    const indexToDelete = currentDealToDelete.findIndex(function(basket){return basket._id === _id;})

    let basketAfterDel = [...currentDealToDelete.slice(0, indexToDelete), ...currentDealToDelete.slice(indexToDelete + 1)]

    this.props.deleteBasketItem(basketAfterDel);
  }

  // ON INCREMENTING
  onIn(_id){
    this.props.updateBasket(_id, 1, this.props.basket);
  }

  // ON DECREMENTING
  onDec(_id, quantity){
    if(quantity > 1){
      this.props.updateBasket(_id, -1, this.props.basket);
    }

  }
  render(){
    if(this.props.basket[0]){
      return this.renderBasket();
    } else {
        return this.renderBasketEmpty();
      }
    }

    // SUPER PROPS
    constructor(){
      super();
      this.state = {

        // Modal closed in state initially
        showModal:false
      }
    }

    // OPEN MODAL
    open(){
      this.setState({showModal:true})
    }

    // CLOSE MODAL
    close(){
      this.setState({showModal:false})
    }

    // BLANK BASKET
    renderBasketEmpty(){
      return(
        <div></div>
      )
    }

      // DISPLAY DEALS/ITEMS IN THE BASKET COMPONENT
      renderBasket(){
        const basketItemsList = this.props.basket.map(function(basketArr){
          return(
            <Panel key={basketArr._id}>
              <Row>
                <Col xs={12} md={12}>
                  <h2>{basketArr.title}</h2>
                </Col>
                <Col xs={12} md={2}>
                  <h4>€{basketArr.price}</h4>
                </Col>
                <Col xs={12} md={2}>
                  <h4>Quantity: <Label bsStyle="info">{basketArr.quantity}</Label></h4>
                </Col>
                <Col xs={6} md={8}>
                  <ButtonGroup style={{minWidth: '250px'}}>
                    <Button onClick={this.onDec.bind(this, basketArr._id, basketArr.quantity)} bsStyle="default" bsSize="small">-</Button>
                    <Button onClick={this.onIn.bind(this, basketArr._id)} bsStyle="default" bsSize="small">+</Button>
                    <Button onClick={this.onDel.bind(this, basketArr._id)} bsStyle="danger" bsSize="small">Remove</Button>
                  </ButtonGroup>
                </Col>
              </Row>
            </Panel>
          )
        }, this)
        return(
          <Panel header="Basket" bsStyle="info" >
            {basketItemsList}
            <Row>
              <Col xs={12} md={12}>
                <h4>Total: {this.props.ttlAmount} </h4>
                <Button onClick={this.open.bind(this)} bsStyle="success" bsSize="small">
                  Checkout
                </Button>
              </Col>
            </Row>
            <Modal show={this.state.showModal} onHide={this.close.bind(this)}>
          <Modal.Header closeButton>
            <Modal.Title>Deal Store</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <h2>SUCCESS!</h2>
            <p>Order is ready!</p>
          </Modal.Body>
          <Modal.Footer>
            <Col xs={4} md={4}>
              <h2>Total is € {this.props.ttlAmount}</h2>
            </Col>
            <Button onClick={this.close.bind(this)}>Close</Button>
          </Modal.Footer>
        </Modal>
          </Panel>
        )
      }
    }

function mapStateToProps(state){
  return{
    basket: state.basket.basket,
    ttlAmount: state.basket.ttlAmount
  }
}


function mapDispatchToProps(dispatch){
  return bindActionCreators({
    deleteBasketItem:deleteBasketItem,
    updateBasket:updateBasket,
    getBasket:getBasket
  }, dispatch)
}

// MAKE CONNECTION == connect
export default connect(mapStateToProps, mapDispatchToProps)(Basket);

DealItem.js

"use strict"

import React from 'react';
import {Row, Well, Col, Button } from 'react-bootstrap';
import {connect} from 'react-redux';

import {bindActionCreators} from 'redux';
import {addBasket, updateBasket} from '../../actions/basketActions';


class DealItem extends React.Component{

  handleBasket(){
    const deal = [...this.props.basket, {
      _id: this.props._id,
      title: this.props.title,
      description: this.props.description,
      price: this.props.price,
      quantity: 1
    }]

    // CHECK IF ITEM IN BASKET
    // IF EMPTY
    // DISPLAY ERROR MESSAGE
    if(this.props.basket.length > 0){
      let _id = this.props._id;

      let basketIndex = this.props.basket.findIndex(function(basket){
        return basket._id === _id;
      })

      // == -1 ADD TO BASKET
      if (basketIndex === -1){
        this.props.addBasket(deal);
      } else {
        // THEN UPDATE BASKET
        this.props.updateBasket(_id, 1, this.props.basket)
      }
    } else {
      this.props.addBasket(deal);
    }
  }
  // RENDER HTML
  render(){
    return(
      <Well>
        <Row>
          <Col xs={12}>
            <h2>{this.props.title}</h2>
            <p>{this.props.description}</p>
            <h4>€ {this.props.price}</h4>
            <Button onClick={this.handleBasket.bind(this)}
              bsStyle='primary'>Purchase</Button>
          </Col>
        </Row>
      </Well>
    )
  }
}

function mapStateToProps(state){
  return{
    basket: state.basket.basket
  }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators({
    addBasket:addBasket,
    updateBasket: updateBasket
  }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(DealItem);

basketReducers.js

"use strict"

export function basketReducers(state={basket:[]}, action) {
  switch (action.type) {
    // ADD***********************
      case "ADD_TO_BASKET":
      return {...state, basket:action.payload,
      ttlAmount: totals(action.payload).dealAmount,
      totalQuantity: totals(action.payload).quantity}
      break;
      // UPDATE *****************
      case "UPDATE_BASKET":
      return {...state, basket:action.payload,
      ttlAmount: totals(action.payload).dealAmount,
      totalQuantity: totals(action.payload).quantity}
      break;

      // GET *******************
      case "GET_BASKET":
      return{...state, basket:action.payload, ttlAmount:totals(action.payload).dealAmount,
      totalQuantity: totals(action.payload).quantity}

      // DELETE ****************
      case "DELETE_BASKET_ITEM":
        return {...state, basket:action.payload,
        ttlAmount: totals(action.payload).dealAmount,
        totalQuantity: totals(action.payload).quantity}
        break;
  }
  return state
}

// TOTALING
export function totals(payloadArr){
  const ttlAmount = payloadArr.map(function(basketArr){
    return basketArr.price * basketArr.quantity;
  }).reduce(function(y, z) {
    return y + z;
  }, 0); //start from 0 and add onto


const totalQuantity = payloadArr.map(function(quantity){
  return quantity.quantity;
}).reduce(function(y, z) {
  return y + z;
}, 0);
  return {dealAmount:ttlAmount.toFixed(2), quantity:totalQuantity}
}

apiServer.js

//IMPORT EXPRESS
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

// ROUTES
var index = require('./routes/index');
var users = require('./routes/users');

// COOKIES & SESSION
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);

var app = express();

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));


// MONGOOSE FOR THE API FOR DEALS
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/dealshop');

// DEALS COLLECTION
var Deals = require('./collections/deals.js');

// START CONN

var db = mongoose.connection;
db.on('error', console.error.bind(console, '#########~~~~~~ ERROR'));

app.use(session({
  secret: 'anonStr',
  saveUninitialized: false,
  resave: false,
  cookie: {maxAge: 1000 * 60 * 60 * 24 * 2},
  store: new MongoStore({mongooseConnection: db, ttl: 1 * 24 * 30 * 60})
  // time to leave
}))

// SAVE BASKET
app.post('/basket', function(req, res){
  var basket = req.body;
  req.session.basket = basket;
  req.session.save(function(err){
    if(err){
      throw err;
    }
    res.json(req.session.basket);
  })
});

// GET THE BASKET
app.get('/basket', function(req, res){
  if (typeof req.session.basket !== 'undefined') {
    res.json(req.session.basket);
  }
});

// END THE COOKIE SESSION

// POST DEALS
app.post('/deals', function(req, res){
  var deal = req.body;

  Deals.create(deal, function(err, deals){
    if(err){
      throw err;
    }
    res.json(deals);
  })
});

// GET DEALS
app.get('/deals', function(req, res){
  Deals.find(function(err, deals){
    if(err){
      throw err;
    }
    res.json(deals);
  })
});

// DELETE DEALS
app.delete('/deals/:_id', function(req, res){
  var query = {_id: req.params._id};
  Deals.remove(query, function(err, deals){
    if(err){
      throw err;
    }
      res.json(deals);
    })
});

// FINISH API SERVER


app.listen(3001, function(err){
  if(err){
    return console.log(err);
  }
  console.log('API running on 3001');
})

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// MONGOOSE FOR THE API FOR DEALS
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/dealshop');

// DEALS COLLECTION
var Deals = require('./collections/deals.js');

// POST DEALS
app.post('/deals', function(req, res){
  var deal = req.body;

  Deals.create(deal, function(err, deals){
    if(err){
      throw err;
    }
    res.json(deals);
  })
});

// GET DEALS
app.get('/deals', function(req, res){
  Deals.find(function(err, deals){
    if(err){
      throw err;
    }
    res.json(deals);
  })
});

// DELETE DEALS
app.delete('/deals/:_id', function(req, res){
  var query = {_id: req.params._id};
  Deals.remove(query, function(err, deals){
    if(err){
      throw err;
    }
      res.json(deals);
    })
});


// app.use('/', index);
// app.use('/users', users);

app.get('/', function(req, res) {
    res.sendFile(path.resolve(__dirname, 'public', 'index.html'))
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

package.json

{
  "name": "dealstore",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "devDependencies": {
    "nodemon": "^1.11.0",
    "redux-logger": "^3.0.6",
    "webpack": "^3.5.5"
  },
  "dependencies": {
    "axios": "^0.16.2",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-1": "^6.24.1",
    "body-parser": "~1.17.1",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.3",
    "express": "^4.15.4",
    "jade": "~1.11.0",
    "mongoose": "^4.11.8",
    "morgan": "~1.8.1",
    "react": "^15.4.1",
    "react-bootstrap": "^0.31.2",
    "react-dom": "^15.4.1",
    "react-redux": "^5.0.5",
    "react-router": "^3.0.4",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0",
    "serve-favicon": "~2.4.2"
  }
}

server.js

'use strict'
var express = require('express');
var app = express();
var path = require('path');


app.use(express.static('public'));


app.get('/', function(req, res){
 res.sendFile(path.resolve(__dirname,'public', 'index.html'))
});
app.listen(3000, function(){console.log('App web-server listening onport 3000');
});
Styx
  • 9,863
  • 8
  • 43
  • 53
cala
  • 767
  • 4
  • 11
  • 28

0 Answers0