Mobx: Question about fetching from api

Created on 2 Jul 2016  路  1Comment  路  Source: mobxjs/mobx

I am using ag-grid which requires "rowData" and "columnDefs" to be fed with details. The data to be fed into rowData has to be fetched from an api which depends on two observables provided (start and end date). The question is what should be the right way of fetching the data as long as the two observables change, should i be using @computed get or @action?

I have tried @action and passing it to rowData but it does not seem to fetch it automatically when the observables changes.
The other method i tried was to fetch it inside @computed get and pass the returned response to an @action but that threw an error (not allowed to assign new values to computed properties.) thus i am clueless on how to proceed

"columnDefs" depends on the data fetched from the api

Most helpful comment

Hey @Dauth, I think, you are mixing thigs up.
@computed get should be used for pure functional computation, that depends only of your app's state and shouldn't DO anything. Only return the computed value.
@action a function, that is allowed to change change your app state.

I would do it like this:

class MyDataState {

  @observable startDate = 0;
  @observable endDate = 5;

  @observable rowData = {};

  @computed get columnDefs() {
    // pure computation
    return this.rowData.colums.filter(/*some filtering for example*/);
  }

  @observable isLoading = false;
  @observable loadingError = undefined;

  @action changeStartDate(date) {
    this.startDate = date;
  }

  @action changeEndDate(date) {
    this.endDate = date;
  }

  @action startLoading() {
    this.isLoading = true;
  }

  @action stopLoading(withError) {
    this.isLoading = false;
    this.loadingError = withError;
  }

  @action updateData(data) {
    this.rowData = data.row;
  }

  constructor() {
    autorun(() => {
      this.startLoading();
      api.getData({ start: this.startDate, end: this.endDate })
        .then(data => {
          this.updateData(data);
          this.stopLoading();
        })
        .catch(err => {
          this.stopLoading(err);
        });
    });
  }
}

>All comments

Hey @Dauth, I think, you are mixing thigs up.
@computed get should be used for pure functional computation, that depends only of your app's state and shouldn't DO anything. Only return the computed value.
@action a function, that is allowed to change change your app state.

I would do it like this:

class MyDataState {

  @observable startDate = 0;
  @observable endDate = 5;

  @observable rowData = {};

  @computed get columnDefs() {
    // pure computation
    return this.rowData.colums.filter(/*some filtering for example*/);
  }

  @observable isLoading = false;
  @observable loadingError = undefined;

  @action changeStartDate(date) {
    this.startDate = date;
  }

  @action changeEndDate(date) {
    this.endDate = date;
  }

  @action startLoading() {
    this.isLoading = true;
  }

  @action stopLoading(withError) {
    this.isLoading = false;
    this.loadingError = withError;
  }

  @action updateData(data) {
    this.rowData = data.row;
  }

  constructor() {
    autorun(() => {
      this.startLoading();
      api.getData({ start: this.startDate, end: this.endDate })
        .then(data => {
          this.updateData(data);
          this.stopLoading();
        })
        .catch(err => {
          this.stopLoading(err);
        });
    });
  }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

josvos picture josvos  路  3Comments

geohuz picture geohuz  路  3Comments

Niryo picture Niryo  路  3Comments

mehdi-cit picture mehdi-cit  路  3Comments

cafreeman picture cafreeman  路  4Comments