1

So I am trying to make my UI in React dependent on my JSON file. I have read a lot of articles in here, but I haven't found something, I could both understand and use. I think loading json data from local file into React JS is the closest I have come, but I am not sure how to apply it to my program.

Pre-knowledge; I am using ES6 through this setup.

I am trying to base my React on a local JSON-file by .map through it and then render a div every time, there's a key. Later I also want to make some of the JSON values to <p></p>, but I am not that far yet.

I tried to follow the tutorial, which accesses a JSON file via an AJAX call, but couldn't make it work in the above mentioned setup - and yes I found out that I can't use getInitialState in ES6. No matter what I tried, it kept giving me a parse error or can't find myFile.json.

So what I need is something like this

var data = require('./myFile.json');

class theWholeThing extends React.Component {
 render() {
   <div className="container">
        return <makeDiv key={key} item={item}/>;
   </div>
    }
  }

class makeDiv extends React.Component {
    {data.levels.map(function (item, key) { //mapping through the key "levels" in json
       return <div className="itIsVisible"></div>;
    })}
}

So every time there's a a level in "levels", lvl1, lvl2, lvl3, there should be a div. If I make another level in json, there should be another div in the UI.

Any suggestions is appreciated or links to other articles.

I am new to React, json and AJAX calls and little below intermediate (or a bit over beginner) programmer in general.

PS I am not trying to make a game, more of an interactive way of getting information through a simple but intuitive GUI.

Community
  • 1
  • 1
Mathias Egekvist
  • 358
  • 3
  • 14

2 Answers2

2

You need to use a json loader for webpack: https://github.com/webpack/json-loader

const json = require('json!./myFile.json');

Edit: Actually you should just be able to do const json = require('./myFile.json');

However this is not an AJAX request, it will build the file into your app.

To fetch a json script you could use something like: https://github.com/github/fetch

fetch('/myFile.json')
  .then(response => {
    return response.json()
  }).then(data => {
    this.setState({ levels: data.levels });
  }).catch(ex => {
    console.log('parsing failed', ex)
  })

Also you can set the initial state of the component in the constructor:

constructor(props) {
   super(props)
   this.state = { ... }
}
Dominic
  • 62,658
  • 20
  • 139
  • 163
0

Here is the get json part with ajax. Start with server.js.

'use strict';

let bodyParser = require('body-parser');
let express = require('express');
let favicon = require('serve-favicon');

let path = require('path');
let port = Number(3500);

let routes = require('./routes');

let app = express();
let server = app.listen(port);

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

app.use('/', express.static('ui-dist'));
app.use('/routes', routes);

app.use(favicon(path.join(__dirname, '..', 'ui-dist', 'img', 'favicon.ico')));
app.get('/', function(req, res){ res.sendfile(__dirname + '/index.html', [], null); });
The route.

'use strict';

let express = require('express');
let router = express.Router();

let getSetData = require('./routes/getsetdata');

router.get('/getData', function(req, res) {
  let getDataDone = function(data){ res.send(data); };
  getSetData.getData(getDataDone);
});

router.post('/setData', function(req, res) {
  let setDataDone = function(data){ res.send(data); };
  console.log(req.body);
  getSetData.setData(req.body, setDataDone);
});

module.exports = router;

The getSetData.

'use strict';

var fs = require('fs');

var rootDataPath = './data';

var getData = function(doneCallBack) {
  var filePath = rootDataPath + '/basic.json';
  var jsonReadCallBack = function(err, data){
    if (err) doneCallBack('Data readFile error ' + filePath);
    else {
      var jsonData = JSON.parse(data.toString());
      doneCallBack(jsonData);
    }
  };
  fs.readFile(filePath, jsonReadCallBack);
};

var setData = function(data, doneCallBack) {
  var filePath = rootDataPath + '/basic.json';
  var writeFileCallBack = function (err) {
    if (err) console.log('error saving Data.json file ');
    doneCallBack('ok');
  };
  fs.writeFile(filePath, JSON.stringify(data, null, 2), writeFileCallBack);
};

module.exports.getData = getData;
module.exports.setData = setData;

The ajax.api.

import request from 'superagent';

import apiActions from '../actions/api.Actions';
import saActions from '../actions/sa.Actions';

module.exports = {
  getData() { request.get('/routes/getData').end((err, res) => { this.gotData(res.body); }); },
  gotData(data) { saActions.gotData1(data); saActions.gotData2(data); saActions.gotData3(data); },
  setData(data) { request.post('/routes/setData').send(data).end((err, res) => { apiActions.apiInitDone(); }) },
};

The api.store.

import Reflux from 'reflux';

import Actions from '../actions/api.Actions';
import ApiFct from '../utils/sa.api';

let ApiStoreObject = {
  newData: {
    "React version": "0.14",
    "Project": "ReFluxSuperAgent",
    "currentDateTime": new Date().toLocaleString()
  },
  listenables: Actions,
  apiInit() { ApiFct.setData(this.newData); },
  apiInitDone() { ApiFct.getData(); },
  apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;

The data.store.

import Reflux from 'reflux';

import Actions from '../actions/sa.Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';

function _GotData(data) { this.data1 = data; BasicStore.trigger('data1'); }

let BasicStoreObject = {
  init() { this.listenTo(AddonStore, this.onAddonTrigger); },
  data1: {},
  listenables: Actions,
  mixins: [MixinStoreObject],
  onGotData1: _GotData,
  onAddonTrigger() { BasicStore.trigger('data2'); },
  getData1() { return this.data1; },
  getData2() { return AddonStore.data2; },
  getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;

The component.

import React from 'react';

import BasicStore from '../stores/Basic.Store';

let AppCtrlSty = {
  height: '100%',
  padding: '0 10px 0 0'
}

const getState = () => {
  return {
    Data1: BasicStore.getData1(),
    Data2: BasicStore.getData2(),
    Data3: BasicStore.getData3()
  };
};

class AppCtrlRender extends React.Component {
   render() {
    let data1 = JSON.stringify(this.state.Data1, null, 2);
    let data2 = JSON.stringify(this.state.Data2, null, 2);
    let data3 = JSON.stringify(this.state.Data3, null, 2);
    return (
      <div id='AppCtrlSty' style={AppCtrlSty}>
        React 1.4 ReFlux with SuperAgent<br/><br/>
        Data1: {data1}<br/><br/>
        Data2: {data2}<br/><br/>
        Data3: {data3}<br/><br/>
      </div>
    );
  }
}

export default class AppCtrl extends AppCtrlRender {
  constructor() {
    super();
    this.state = getState();
  }

  componentDidMount() { this.unsubscribe = BasicStore.listen(this.storeDidChange.bind(this)); }
  componentWillUnmount() { this.unsubscribe(); }
  storeDidChange(id) {
    switch (id) {
      case 'data1': this.setState({Data1: BasicStore.getData1()}); break;
      case 'data2': this.setState({Data2: BasicStore.getData2()}); break;
      case 'data3': this.setState({Data3: BasicStore.getData3()}); break;
      default: this.setState(getState());
    }
  }
}

The app.js.

'use strict';

import React  from 'react';
import ReactDom  from 'react-dom';

import AppCtrl from './components/app.ctrl.js';
import Actions from './actions/api.Actions';
import ApiStore from './stores/Api.Store';

window.ReactDom = ReactDom;

Actions.apiInit();

ReactDom.render( <AppCtrl />, document.getElementById('react') );

From https://github.com/calitek/ReactPatterns React.14/ReFluxSuperAgent.

J. Mark Stevens
  • 4,911
  • 2
  • 13
  • 18