Example

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';

import jobPropTypes from '../Jobs/components/Job/jobPropTypes';
import jobLogPropTypes from '../JobLogs/jobLogPropTypes';
import {
  PROCESSING_IN_PROGRESS,
  PROCESSING_FINISHED,
  PARSING_IN_PROGRESS,
} from '../Jobs/jobStatuses';
import { DataFetcherContextProvider } from './DataFetcherContext';


import css from 'DataFetcher.css';

const DEFAULT_UPDATE_INTERVAL = 5000;

class DataFetcher extends Component {
static manifest = Object.freeze({
    jobs: {
      type: 'okapi',
      path: `metadata-provider/jobExecutions?query=(status=("${PROCESSING_IN_PROGRESS}" OR "${PROCESSING_FINISHED}" OR "${PARSING_IN_PROGRESS}"))`,
      accumulate: true,
      throwErrors: false,
    },
    logs: {
      type: 'okapi',
      path: 'metadata-provider/logs?landingPage=true',
      accumulate: true,
      throwErrors: false,
    },
  });

  static propTypes = {
    children: PropTypes.oneOfType([
      PropTypes.arrayOf(PropTypes.node),
      PropTypes.node,
    ]).isRequired,
    resources: PropTypes.shape({
      jobs: PropTypes.shape({
        records: PropTypes.arrayOf(
          PropTypes.shape({
            jobExecutionDtos: PropTypes.arrayOf(jobPropTypes).isRequired,
          }),
        ).isRequired,
      }),
      logs: PropTypes.shape({
        records: PropTypes.arrayOf(
          PropTypes.shape({
            logs: PropTypes.arrayOf(jobLogPropTypes).isRequired,
          }),
        ).isRequired,
      }),
    }).isRequired,
    updateInterval: PropTypes.number,
  };

  static defaultProps = {
    updateInterval: DEFAULT_UPDATE_INTERVAL,
  };

  state = {
    contextData: {},
  };

  constructor(){
	super();
	
  }

  componentDidMount() {
    this.setInitialState();
    this.getResourcesData();
    this.updateResourcesData();
  }

  componentWillUnmount() {
    clearInterval(this.intervalId);
  }

  render() {
    const { children } = this.props;
    const { contextData } = this.state;

    return (
      <DataFetcherContextProvider value={contextData}>
        {children}
      </DataFetcherContextProvider>
    );
  }

  updateResourcesData() {
    const { updateInterval } = this.props;

    this.intervalId = setInterval(this.getResourcesData, updateInterval);
  }

  setInitialState() {
    const { mutator } = this.props;
    const initialContextData = {};

    Object.keys(mutator)
      .forEach(resourceName => {
        initialContextData[resourceName] = {
          hasLoaded: false,
        };
      });

    this.setState({
      contextData: initialContextData,
    });
  }

  getResourcesData = async () => {
    const { mutator } = this.props;

    const fetchResourcesPromises = Object.values(mutator)
      .reduce((res, resourceMutator) => {
        return res.concat(this.getResourceData(resourceMutator));
      }, []);

    try {
      await Promise.all(fetchResourcesPromises);

      this.mapResourcesToState();
    } catch (e) {
      // TODO: should be described in UIDATIMP-53
    }
  };

  async getResourceData({ GET, reset }) {
    // accumulate: true in manifest saves the results of all requests
    // because of that it is required to clear old data by invoking reset method before each request
    reset();
    await GET();
  }

  mapResourcesToState() {
    const { resources } = this.props;
    const contextData = {};

    Object.entries(resources)
      .forEach(([resourceName, resourceValue]) => {
        contextData[resourceName] = {
          hasLoaded: true,
          itemsObject: get(resourceValue, ['records', 0], {}),
        };
      });

    this.setState({
      contextData,
    });
  }
}

export default DataFetcher;