zakandrewking / escher

Build, share, and embed visualizations of metabolic pathways.
https://escher.github.io
Other
210 stars 78 forks source link

Cannot read property 'apply_metabolite_data_to_map' or 'apply_reaction_data_to_map' error | When trying to set both metabolite and reaction data at the same time. #320

Closed alperdokay closed 5 years ago

alperdokay commented 5 years ago

In the scoring part of our algorithm, I use my scores to mark both nodes(metabolites) and paths(reactions) but whichever I do first in the code, marking works perfectly but the other one does not work because of an error called "Cannot read property 'apply_reaction_data_to_map' of undefined"

For example; I firstly implement my object storing reaction scores like { [reaction_name(str)] : [score(int)] } by using set_reaction_data function from JavaScript API. In my opinion, setting reaction data results in a bug because the line coming later than this which is calling set_metabolite_data function does not work. In console, I see that there is an error called "Cannot read property 'apply_reaction_data_to_map' of undefined. "

I somehow put try-catch and mark both reactions and metabolites at the same time but it still seems something to fix for me. I wanted to let you all know. If someone faced with the same issue, could you leave a comment here? @zakandrewking

zakandrewking commented 5 years ago

Could you share some more of your code so I can get a better idea of what might be happening?

One option would be to extend this jsfiddle to recreate the issue:

https://jsfiddle.net/j0dpg872/7/

thanks!

alperdokay commented 5 years ago

Thank you for your answer @zakandrewking!

I use Angular in my web application. The Angular side of the code is the following; I just get the name of a pathway in 'ngOnChanges' and do the remaining part.

ngOnChanges() {
    this.loader.get('recon2', (recon) => {
      let element = d3.select(this.elementRef.nativeElement).select('#map_container_3');
      this.escher.buildPathwayMap(this.name, recon, element, (m) => {
        if (this.fluxes) {
          this.escher.setFluxData(m, this.fluxes);
          }
      });
    });
  }

I also wrote a service to use Escher and separate the code accordingly. Methods I used in 'ngOnChanges' are the following;

buildPathwayMap(pathway, model, element, callback?: (d) => void) {
    let pathwayName = pathway.split(' ').join('-').split('/').join('-').toLowerCase();
    this.http.get(`assets/datasets/visualizations/${pathwayName}.json`)
      .subscribe((data:any) => {
        let m = escher.Builder(data, this.escherModelForPathway(model, pathway), null, element, this.options);
        callback(m);
      }, () =>
        escher.Builder(null, this.escherModelForPathway(model, pathway), null, element, this.options)
      );
  }
escherModelForPathway(model, pathway) {
    return {
      metabolites: _.values(model.metabolites),
      reactions: _.values(model.reactions).filter(x => x['subsystem'] === pathway),
      genes: []
    }
  }

Both of the setting objects are like the following structure; { [name](string): [score](int)}

setFluxData(model, fluxes) {
      // fluxes.results_reaction is an object storing data like {[reaction_name] : [score_of_the_reaction], ...}
      model.set_reaction_data(results_reaction);
      // fluxes.fold_changes is an object storing data like {[metabolite_name] : [change_of_the_metabolite], ...}
      model.set_metabolite_data(fold_changes);
  }

Thank you for your attention and your support. I actually do the same thing with the code you sent on jsfiddle. I wanted to share more details, sorry for not sharing these in the beginning.

alperdokay commented 5 years ago

I forgot to add the error. It was the following;

error

zakandrewking commented 5 years ago

ah, you will need to wait until the map is loaded to run those functions. to make it easier, we provide a callback function option described here:

https://escher.readthedocs.io/en/latest/javascript_api.html#escher.Builder.options.first_load_callback

And example here in the jsfiddle:

https://jsfiddle.net/s4z0pkon/1/

alperdokay commented 5 years ago

Thank you @zakandrewking ! It is now working without an error.