Monday 1 May 2017

Simple React 15.0, React RouterV4 - Not working

I have tried a simple react application with sequelise. I am getting TypeError: Router.match is not a function in the browser, when I type http://localhost:8000/api/characters/top. I have attached all the files i have used:

newedenfacessequelize  
 app

  actions
     FooterActions.js
     HomeActions.js
  components
     App.js
     Footer.js
     Home.js
  stores
     alt.js
     main.js
     routes.js
  bin
     www
  public
     js
     bundle.js
     vendor.bundle.js
     vendor.js
  server
    config
      config.json
    models
      Character.js
    routes
      index.js
  views
      index.html
  app.js
  gulpfile.js
  package.json

===

FooterActions.js

import alt from '../alt';

  class FooterActions {
    constructor() {
      this.generateActions(
        'getTopCharactersSuccess',
        'getTopCharactersFail'
      );
    }

    getTopCharacters() {
      $.ajax({ url: '/api/characters/top' })
        .done((data) => {
          //console.log(data);
           console.log("Actions: "+this.actions);
          this.actions.getTopCharactersSuccess();
        })
        .fail((jqXhr) => {
          this.actions.getTopCharactersFail(jqXhr)
        });
    }
  }

export default alt.createActions(FooterActions);

======

HomeActions.js

import alt from '../alt';

class HomeActions {
  constructor() {
    this.generateActions();
  }
}
export default alt.createActions(HomeActions);

======

App.js

import React from 'react';
import Footer from './Footer';

class App extends React.Component {
  render() {
    return (
      <div>
        <Footer />
      </div>
    );
  }
}
export default App;

====

Footer.js

import React from 'react';
import {Link} from 'react-router';
import FooterStore from '../stores/FooterStore'
import FooterActions from '../actions/FooterActions';

class Footer extends React.Component {
  constructor(props) {
    super(props);
    this.state = FooterStore.getState();
    this.onChange = this.onChange.bind(this);
  }

  componentDidMount() {
    FooterStore.listen(this.onChange);
    FooterActions.getTopCharacters();
  }

  componentWillUnmount() {
    FooterStore.unlisten(this.onChange);
  }

  onChange(state) {
    this.setState(state);
  }

  render() {
    let leaderboardCharacters = this.state.characters.map(function(character) {
      return (
        <li key={character.characterId}>
          <Link to={'/characters/' + character.characterId}>
            <img className='thumb-md' src={'http://image.eveonline.com/Character/' + character.characterId + '_128.jpg'} />
          </Link>
        </li>
      );
    });

      return (
        <footer>
          <div className='container'>
            <div className='row'>
              <div className='col-sm-5'>
                <h3 className='lead'><strong>Information</strong> and <strong>Copyright</strong></h3>
                <p>Powered by <strong>Node.js</strong>, <strong>MongoDB</strong> and <strong>React</strong> with Flux architecture and server-side rendering.</p>
                <p>You may view the <a href='https://github.com/sahat/newedenfaces-react'>Source Code</a> behind this project on GitHub.</p>
                <p>© 2015 Sahat Yalkabov.</p>
              </div>
              <div className='col-sm-7 hidden-xs'>
                <h3 className='lead'><strong>Leaderboard</strong> Top 5 Characters</h3>
                <ul className='list-inline'>
                  {leaderboardCharacters}
                </ul>
              </div>
            </div>
          </div>
        </footer>
      );
    }
  }

  export default Footer;

=====

Home.js

  import React from 'react';
  import {Link} from 'react-router';
  import HomeStore from '../stores/HomeStore'
  import HomeActions from '../actions/HomeActions';


  class Home extends React.Component {
    constructor(props) {
      super(props);
      this.state = HomeStore.getState();
      this.onChange = this.onChange.bind(this);
    }

    componentDidMount() {
      HomeStore.listen(this.onChange);
    }

    componentWillUnmount() {
      HomeStore.unlisten(this.onChange);
    }

    onChange(state) {
      this.setState(state);
    }

    render() {
      return(
        <div class="alert alert-info">Hello From Home Component</div>
        );
    }
  }

  export default Home;

==========

FooterStore.js

  import alt from '../alt';
  import FooterActions from '../actions/FooterActions';

  class FooterStore {
    constructor() {
      this.bindActions(FooterActions);
      this.characters = [];
    }

    onGetTopCharactersSuccess() {
      this.characters = "Hi Buddy";
    }

    onGetTopCharactersFail(jqXhr) {
      //toastr.error(jqXhr.responseJSON && jqXhr.responseJSON.message || jqXhr.responseText || jqXhr.statusText);
       this.characters = "aden";
    }
  }

  export default alt.createStore(FooterStore);

========

HomeStore.js

  import alt from '../alt';
  import HomeActions from '../actions/HomeActions';

  class HomeStore {
    constructor() {
      this.bindActions(HomeActions);
      this.characters = [];
    }

  }

  export default alt.createStore(HomeStore);

===========

alt.js

  import Alt from 'alt';

  export default new Alt();

=====

main.js

  import React from 'react';
  import Router from 'react-router';
  import ReactDOM from 'react-dom';
  import App from './components/App';

  ReactDOM.render(<App />, document.getElementById('app'));

=====

routes.js

  import React from 'react';
  import {Route} from 'react-router';
  import App from './components/App';
  import Home from './components/Home';


  export default (
      <Route component={App} >
        <Route path="/" component={Home} />
      </Route>
  );

======

bin/www

  //This will be our application entry. We will set up our server here
  const http = require('http');
  const app =  require('../app');


  const port = parseInt(process.env.PORT, 10) || 8000;
  app.set('port', port);


  const server = http.createServer(app);

  server.listen( app.get('port'), function(){ 
    console.log('Express server listening on:'+app.get('port'));}
   );

=====

config.json

  {
    "development": {
      "username": "root",
      "password": "xxxx",
      "database": "todos",
      "host": "localhost",
      "dialect": "mysql"
    }
  }

=====

Character.js

  module.exports = (sequelize, DataTypes) => {
    const Character =  sequelize.define('Character', {
      characterId: {
        type: DataTypes.STRING,
        unique: true,
        index:true
      },
      name:{
        type: DataTypes.STRING,
      },
      race:{
        type: DataTypes.STRING,
      },
      gender:{
        type: DataTypes.STRING,
      },
      bloodline:{
        type: DataTypes.STRING,
      },
      wins:{
        type: DataTypes.NUMBER,
        allowNull: false,
        defaultValue:0,
      },
      losses:{
        type: DataTypes.NUMBER,
        allowNull: false,
        defaultValue:0,
      },
      reports:{
        type: DataTypes.NUMBER,
        allowNull: false,
        defaultValue:0,
      },
      random:{
        type: DataTypes.STRING,
        allowNull: false,
      },
      voted: { 
        type: DataTypes.BOOLEAN, 
        defaultValue: false
      },
    });
    return Character;
  };

==========

index.js

  'use strict';

  var fs        = require('fs');
  var path      = require('path');
  var Sequelize = require('sequelize');
  var basename  = path.basename(module.filename);
  var env       = process.env.NODE_ENV || 'development';
  var config    = require(__dirname + '/../config/config.json')[env];
  var db        = {};

  if (config.use_env_variable) {
    var sequelize = new Sequelize(process.env[config.use_env_variable]);
  } else {
    var sequelize = new Sequelize(config.database, config.username, config.password, config);
  }

  fs
    .readdirSync(__dirname)
    .filter(function(file) {
      return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
    })
    .forEach(function(file) {
      var model = sequelize['import'](path.join(__dirname, file));
      db[model.name] = model;
    });

  Object.keys(db).forEach(function(modelName) {
    if (db[modelName].associate) {
      db[modelName].associate(db);
    }
  });

  db.sequelize = sequelize;
  db.Sequelize = Sequelize;

  module.exports = db;

===========

index.js

  var Character = require('../models/Character');
  var express = require('express');
  var router = express.Router();

  router
    .get('/api/characters/top', function(req, res, next) {
        Character
        .findAll()
        .then(characters => res.status(200).send(characters))
        .catch(error => res.status(400).send(error));     
    })

    module.exports = router;

================

index.html

  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>New Eden Faces</title>

  </head>
  <body>
    Still not working
    <div id="app"></div>
    <script src="/js/vendor.js"></script>
    <script src="/js/vendor.bundle.js"></script>
    <script src="/js/bundle.js"></script>
  </body>
  </html>

=============== app.js

    // Babel ES6/JSX Compiler
    require('babel-register');

    var express = require('express');
    var logger = require('morgan');
    var bodyParser = require('body-parser');
    var path = require('path');
    var app = express();
    var React = require('react');
    var Router = require('react-router');
    var ReactDOM = require('react-dom/server');
    var swig  = require('swig');
    var _ = require('underscore');
    var Character = require('./server/models/Character');
    var fs = require('fs');
    var log4js = require('log4js');
    var routes = require('./app/routes');

    //app.use(logger('dev'));


    let characterroute = require('./server/routes/index');

    //Change the build path
    app.use( express.static(path.join(__dirname,'public')));

    // create a write stream (in append mode)
    var accessLogStream = fs.createWriteStream(__dirname + '/access.log', {flags: 'a'})

    // setup the logger
    app.use(logger('combined', {stream: accessLogStream}));

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

    //Set up a default catch-all route that sends back a welcome message in JSON format
    app.use('/api/characters/top', characterroute);

    app.use(function(req, res) {
      Router.match({ routes: routes.default, location: req.url }, function(err, redirectLocation, renderProps) {
        if (err) {
          res.status(500).send(err.message)
        } else if (redirectLocation) {
          res.status(302).redirect(redirectLocation.pathname + redirectLocation.search)
        } else if (renderProps) {
            var html = ReactDOM.renderToString(React.createElement(Router.RoutingContext, renderProps));
            var page = swig.renderFile('views/index.html', { html: html });
            res.status(200).send(page);
        } else {
          res.status(404).send('Page Not Found')
        }
      });
    });


    module.exports = app;

==================

gulpfile.js

  var gulp = require('gulp');
  var concat = require('gulp-concat');
  var babelify = require('babelify');
  var browserify = require('browserify');
  var buffer = require('vinyl-buffer');
  var source = require('vinyl-source-stream');

  var dependencies = [
    'alt',
    'react',
    'react-dom',
    'react-router',
    'underscore'
  ];

  /*
   |--------------------------------------------------------------------------
   | Combine all JS libraries into a single file for fewer HTTP requests.
   |--------------------------------------------------------------------------
   */
  gulp.task('vendor', function() {
    return gulp.src([
      'bower_components/jquery/dist/jquery.js',
      'bower_components/bootstrap/dist/js/bootstrap.js',
      'bower_components/magnific-popup/dist/jquery.magnific-popup.js',
      'bower_components/toastr/toastr.js'
    ]).pipe(concat('vendor.js'))
      .pipe(gulp.dest('public/js'));
  });

  /*
   |--------------------------------------------------------------------------
   | Compile third-party dependencies separately for faster performance.
   |--------------------------------------------------------------------------
   */
  gulp.task('browserify-vendor', function() {
    return browserify()
      .require(dependencies)
      .bundle()
      .pipe(source('vendor.bundle.js'))
      .pipe(buffer())
      .pipe(gulp.dest('public/js'));
  });

  /*
   |--------------------------------------------------------------------------
   | Compile only project files, excluding all third-party dependencies.
   |--------------------------------------------------------------------------
   */
  gulp.task('browserify', ['browserify-vendor'], function() {
    return browserify({ entries: 'app/main.js', debug: true })
      .transform(babelify, { presets: ['es2015', 'react'] })
      .bundle()
      .pipe(source('bundle.js'))
      .pipe(buffer())
      .pipe(gulp.dest('public/js'));
  });


  gulp.task('default', ['vendor','browserify']);

=================

package.json

  {
    "name": "newedenfacessequelize",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "start": "nodemon ./bin/www",
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "babel": {
      "presets": [
        "es2015",
        "stage-0",
        "react"
      ]
    },
    "keywords": [
      "react",
      "reactjs",
      "pagination",
      "paginator",
      "bootstrap",
      "reload",
      "babel",
      "react-transform",
      "react-component"
    ],
    "dependencies": {
      "alt": "^0.18.6",
      "async": "^2.4.0",
      "body-parser": "^1.17.1",
      "classnames": "^2.2.5",
      "colors": "^1.1.2",
      "compression": "^1.6.2",
      "express": "^4.15.2",
      "history": "^4.6.1",
      "log4js": "^1.1.1",
      "mongoose": "^4.9.6",
      "morgan": "^1.8.1",
      "paginator": "^1.0.0",
      "prop-types": "^15.5.8",
      "react": "^15.5.4",
      "react-dom": "^15.5.4",
      "react-router": "^4.1.1",
      "react-syntax-highlight": "0.0.6",
      "request": "^2.81.0",
      "serve-favicon": "^2.4.2",
      "socket.io": "^1.7.3",
      "swig": "^1.4.2",
      "underscore": "^1.8.3",
      "xml2js": "^0.4.17"
    },
    "devDependencies": {
      "babel-core": "^6.24.1",
      "babel-eslint": "^7.2.3",
      "babel-preset-es2015": "^6.24.1",
      "babel-preset-react": "^6.24.1",
      "babel-preset-stage-0": "^6.24.1",
      "babel-register": "^6.24.1",
      "babelify": "^7.3.0",
      "bootstrap": "^3.3.7",
      "bower": "^1.8.0",
      "browserify": "^14.3.0",
      "chai": "^3.5.0",
      "cross-env": "^4.0.0",
      "css-loader": "^0.28.0",
      "enzyme": "^2.8.2",
      "eslint": "^3.19.0",
      "eslint-plugin-react": "^6.10.3",
      "expect": "^1.20.2",
      "file-loader": "^0.11.1",
      "gulp": "^3.9.1",
      "gulp-autoprefixer": "^3.1.1",
      "gulp-concat": "^2.6.1",
      "gulp-cssmin": "^0.1.7",
      "gulp-if": "^2.0.2",
      "gulp-less": "^3.3.0",
      "gulp-plumber": "^1.1.0",
      "gulp-uglify": "^2.1.2",
      "gulp-util": "^3.0.8",
      "jsdom": "^10.0.0",
      "less": "^2.7.2",
      "less-loader": "^4.0.3",
      "mkdirp": "^0.5.1",
      "mocha": "^3.3.0",
      "react-addons-test-utils": "^15.5.1",
      "react-hot-loader": "^1.3.1",
      "rimraf": "^2.6.1",
      "style-loader": "^0.16.1",
      "url-loader": "^0.5.8",
      "vinyl-buffer": "^1.0.0",
      "vinyl-source-stream": "^1.1.0",
      "watchify": "^3.9.0",
      "webpack": "^2.4.1"
    },
    "license": "MIT"
  }

Please help to render this simple serialize React page. Thanks, Priya



via Priya

No comments:

Post a Comment