Component is rendered with empty props ReactJs + Meteor


#1

I study Meteor + ReactJs. I try to use charting library but props is empty when I tries to render the component.

I took chart example from https://github.com/rrag/react-stockcharts/blob/master/docs/lib/charts/CandleStickStockScaleChart.jsx

code example:

import React, { Component } from ‘react’;
import { createContainer } from ‘meteor/react-meteor-data’;
import { Gold } from ‘…/…/imports/collections/gold’;
import CandleStickStockScaleChart from ‘./barchart’;
import d3 from ‘d3’;

const PER_PAGE = 100;

class BarChartHandler extends Component {
componentWillMount() {
this.page = 1;
}

handleButtonClick() {
Meteor.subscribe(‘gold_h1’, PER_PAGE * (this.page + 1));
this.page += 1;
}

render() {
const parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
const data = this.props.candles.map(candle => {
d = {};
d.open = +candle.open;
d.close = +candle.close;
d.high = +candle.high;
d.low = +candle.low;
d.date = new Date(parseDate(candle.timestamp).getTime());
return d;
});

return (        
    <div>        
        <div>
            <CandleStickStockScaleChart data={data} />
        </div>
    </div>
);

}
};

export default createContainer(() => {
// set up subscription
Meteor.subscribe(‘gold_h1’, PER_PAGE);

// return an object. Whatever we return will be sent to BarCharHandler
// as props
return { candles: Gold.find({}).fetch() };
}, BarChartHandler);

Actual component code

import React from “react”;
import d3 from “d3”;

import ReStock from “react-stockcharts”;

var { ChartCanvas, Chart } = ReStock;

var { CandlestickSeries } = ReStock.series;
var { discontinuousTimeScaleProvider } = ReStock.scale;
var { XAxis, YAxis } = ReStock.axes;

var { fitWidth } = ReStock.helper;

class CandleStickStockScaleChart extends React.Component {

render() {
    var { type, data, width } = this.props;
    console.log('data-----', data);

    return (

        <ChartCanvas width={width} height={400}
                margin={{left: 50, right: 50, top:10, bottom: 30}} type={type}
                seriesName="MSFT"
                data={data}
                xAccessor={d => d.date} xScaleProvider={discontinuousTimeScaleProvider}
                xExtents={[new Date(2012, 0, 1), new Date(2012, 6, 2)]}>

            <Chart id={1} yExtents={d => [d.high, d.low]}>
                <XAxis axisAt="bottom" orient="bottom" ticks={6}/>
                <YAxis axisAt="left" orient="left" ticks={5} />
                <CandlestickSeries />
            </Chart>
        </ChartCanvas>
    );
}

}

CandleStickStockScaleChart.propTypes = {
data: React.PropTypes.array.isRequired,
width: React.PropTypes.number.isRequired,
type: React.PropTypes.oneOf([“svg”, “hybrid”]).isRequired,
};

CandleStickStockScaleChart.defaultProps = {
type: “svg”,
width: 500
};
CandleStickStockScaleChart = fitWidth(CandleStickStockScaleChart);

export default CandleStickStockScaleChart;

Execution logs

data----- []

exception here because data is empty and after data is initialized.

data----- [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, O

What I am doing wrong , Why my props are empty during rendering and how to fix it

Thanks.


#2

Hello @oruchovets,

You can add one more parameter like “loading” along with candles in createContainer() method.

You have to take first subscriptionhandler as mentioned below.

var subscriptionHandle = Meteor.subscribe(‘gold_h1’, PER_PAGE);
var loading = !subscriptionHandle.ready();

so your code will be like this :

export default createContainer(() => {
// set up subscription
var subscriptionHandle = Meteor.subscribe(‘gold_h1’, PER_PAGE);
var loading = !subscriptionHandle.ready();

// return an object. Whatever we return will be sent to BarCharHandler
// as props
return { candles: Gold.find({}).fetch(),loading :loading };
}, BarChartHandler);

and in render method update your code as mentioned below:

render() {

// if data is still loading then display spinner
if (this.data.loading) {
return (



// Add Spinner code to display spinner while data is loading
//like


)
}

// if data is loaded then below will be called

const parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
const data = this.props.candles.map(candle => {
d = {};
d.open = +candle.open;
d.close = +candle.close;
d.high = +candle.high;
d.low = +candle.low;
d.date = new Date(parseDate(candle.timestamp).getTime());
return d;
});

return (






);

}

Regards,
Tarun Sharma
Sr. Developer @ AIMDek Technologies Pvt Ltd
+91 9510657842