0

I am working on project . I am fetching data through API but in meantime it give me an error http://localhost:3000/api/meetups?filter[limit]=undefined. I am not able to fetch data from server through API . Could someone please help me how to fix this undefined in my project . I think it may be error of _limit but sorry I am new to ReactJS and don't have much knowledge to fix this problem .

Code

import React from 'react';
import {Divider, Segment} from 'semantic-ui-react';

import {VehicleTable} from './VehicleTable.jsx';
import {VehicleFilter} from './VehicleFilter.jsx';

const queryParams = ['filter[limit]','_order','_sort','q','_page'];

export default class VehicleList extends React.Component {
  constructor() {
    super();
    this.state = {
      vehicles: [],
      _sort: 'id',
      _page: 1,
      _order: null,
      _limit: 10,
      q: '',
      totalCount: 0,
      loading: false,
     };
    this.loadData = this.loadData.bind(this);
    this.onChangeLimit = this.onChangeLimit.bind(this);
    this.onSubmitFilter = this.onSubmitFilter.bind(this);
    this.onChangePage = this.onChangePage.bind(this);
    this.handleSort = this.handleSort.bind(this);
  }

  directionConverter(order) {
    if (order === 'asc') {
      return 'ascending';
    } else if (order === 'desc') {
      return 'descending';
    } else {
      return null;
    }
  }

  handleSort(clickedColumn) {
    const { _sort, _order } = this.state;

    let newOrder = _order === 'asc' ? 'desc' : 'asc';
    if (_sort !== clickedColumn) {
      newOrder = 'asc';
    }

    this.setState({
      _sort: clickedColumn,
      _page: 1,
      _order: newOrder,
    });

    this.loadData({
      _sort: clickedColumn,
      _page: 1,
      _order: newOrder,
    });
  }

  componentDidMount() {
    this.loadData({});
  }

  onChangeLimit(event, data) {
    if (data.value !== this.state._limit) {
      this.setState({ _limit: data.value, _page: 1  });
      this.loadData({ _limit: data.value, _page: 1  });
    }
  }

  onSubmitFilter(filter) {
    if (filter !== this.state.q) {
      this.setState({ q: filter, _page: 1, loading: true });
      this.loadData({ q: filter, _page: 1 });
    }
  }

  onChangePage(event, data) {
    const {activePage} = data;
    if (activePage !== this.state._page) {
      this.setState({ _page: activePage });
      this.loadData({ _page: activePage });
    }
  }



  loadData(params) {
    const current = this.state;
    queryParams.forEach(function(element) {
      if (!(element in params)) {
        params[element] = current[element];
      }
    });

    const esc = decodeURIComponent;
    const query = Object.keys(params)
      .map(k => esc(k) + '=' + esc(params[k]))
      .join('&');

    // Make a request without limit first to get the total number of data.
    let totalCountQuery = '';
    if (params.q !== "") {
      totalCountQuery = `q=${params.q}`;
    }

    fetch(`http://localhost:3000/api/meetups?${totalCountQuery}`).then(response => {
      if (response.ok) {
        response.json().then(data => {
          this.setState({ totalCount: data.length });
        })
      } else {
        response.json().then(error => {
          console.log(`Failed to load data: ${error.message}`);
        });
      }
      this.setState({loading: false});
    });

    fetch('http://localhost:3000/api/meetups?' + query).then(response => {
      if (response.ok) {
        response.json().then(data => {
          this.setState({ vehicles: data });
        })
      } else {
        response.json().then(error => {
          console.log(`Failed to load data: ${error.message}`);
        });
      }
      this.setState({loading: false});
    })
  }

  render() {
    return (
      <Segment>
        <VehicleFilter
          filter = { this.state.q }
          totalCount = {this.state.totalCount }
          onSubmitFilter = { this.onSubmitFilter }
          loading = { this.state.loading }
        />
      <Divider/>
        <VehicleTable
          vehicles = { this.state.vehicles }
          totalCount = {this.state.totalCount }
          totalPages = { Math.ceil(this.state.totalCount / this.state._limit) }
          currentPage = { this.state._page }
          onChangePage = { this.onChangePage }

          column = { this.state._sort }
          direction = { this.directionConverter(this.state._order) }
          handleSort = { this.handleSort }
          onChangeLimit = { this.onChangeLimit }
          limit = { this.state._limit.toString() }
        />
      </Segment>
    )
  }
}
John
  • 67
  • 1
  • 3
  • 10

1 Answers1

1

you should rename first query param to _limit:

const queryParams = ['_limit','_order','_sort','q','_page'];

and then where you get query params rename back to filter[limit]

   queryParams.forEach(function(element) {
      const name = element === "_limit" ? "filter[limit]" : element;
      if (!(name in params)) {
        params[name] = current[element];
      }
    });

because state have no filter[limit] property but have _limit

  this.state = {
      vehicles: [],
      _sort: 'id',
      _page: 1,
      _order: null,
      _limit: 10,
      q: '',
      totalCount: 0,
      loading: false,
     };
Alex
  • 1,373
  • 8
  • 15
  • it working thanks! Actually , I am using pagination in my project and did some filter of `Loopback` .. Now when I click on next it redirect me to page 2 but data is not render .. Could you please help me how to solve this . – John Mar 20 '19 at 13:24
  • Sorry, but I'm not good at react :( Something simple I can solve, but why component not rerender after state changes, I don't know. Maybe this will be helpful https://stackoverflow.com/questions/24718709/reactjs-does-render-get-called-any-time-setstate-is-called – Alex Mar 20 '19 at 13:44