0

I have the following global helper:

Template.registerHelper('results',function(){
    var valuationId = this._id;
    var valuation = Valuations.findOne({_id: valuationId});
    var targetId = this.targetId;
    var targetTicker = Companies.findOne({_id:targetId}).ticker;
    var targetData = CompaniesData.findOne({ticker: targetTicker});
        return {
            peFy1: targetData.epsFy1 * valuation.PriceEarningsFy1,
            peFy2: targetData.epsFy2 * valuation.priceEarningsFy2
            }
});

When I call this helper through HTML, like so, it works fine:

<div>
    {{results.peFy1}}
</div>

I am not able to display the value when calling the helper through Javascript, per this answer.

<div>
    {{peFy1}}
</div>

Template.ValuationResults.helpers({
    peFy1: function() {
        return UI._globalHelpers.results().peFy1;
    }
});

I've tried writing this in a couple other ways but none work:

return UI._globalHelpers['results']().peFy1;
return Template._globalHelpers.results().peFy1;

For what it's worth, UI._globalHelpers gives an error in Webstorm as being unresolved variables.

I thought the problem might be that I am not passing any parameters to the function, but it works fine through HTML so shouldn't be necessary. Also, adding console.log(this._id) and console.log(this.targetId) within the test helper both return correct results, so those are valid.

CORRECT CODE USING ANSWER BELOW:

getResults = function(valuationId,targetId){
    var valuation = Valuations.findOne({_id: valuationId});
    var targetTicker = Companies.findOne({_id:targetId}).ticker;
    var targetData = CompaniesData.findOne({ticker: targetTicker});
    return {
        peFy1: targetData.epsFy1 * valuation.priceEarningsFy1,
        peFy2: targetData.epsFy2 * valuation.priceEarningsFy2
    }
};
Template.registerHelper('results',function(){
    return getResults();
});

Template.Valuation.helpers({
    peFy1: function() {
        var valuationId = this._id;
        var targetId = this.targetId;
        return getResults(valuationId,targetId).peFy1;
    },
    peFy1: function() {
        var valuationId = this._id;
        var targetId = this.targetId;
        return getResults(valuationId,targetId).peFy1;
    }
});
Community
  • 1
  • 1
Bren
  • 273
  • 1
  • 18
  • Can you paste the error? Is this._id the undefined variable? the syntax UI._globalHelpers.results().peFy1 is fine, provided the context is valid (this._id is set) when you call it. – JeremyK Oct 11 '15 at 22:11
  • Thanks, I added some detail above on the errors I see in the browser. As for your other question, nit sure if I follow. The undefined variable I mentioned was `UI._globalHelpers` itself but I know I shouldn't rely on what Webstorm tells me. If it works when calling from the HTML, I'm not sure why the context would be different calling from JS. Is there anything else I can add here to troubleshoot? – Bren Oct 11 '15 at 22:20
  • where is fixedDisplay defined? what is toFixed? – JeremyK Oct 11 '15 at 22:26
  • `fixedDisplay` is just a helper that sets the number of decimals, using `toFixed()`. Re: your comment on this._id, perhaps I need to pass in `valuationId` and `targetId`? Doesn't work when anyway, but don't see why it would be necessary if they are set within `results` – Bren Oct 11 '15 at 22:31
  • Correction: if I simplify the HTML to just `{{results}}`, I actually get no errors in the browser at all (the `fixedDIsplay` was throwing me off). So I have nothing I can troubleshoot. – Bren Oct 11 '15 at 22:42
  • Adding `console.log(this._id)` and `console.log(this.targetId)` within the `test` helper both return correct results, so those are valid. – Bren Oct 11 '15 at 22:45
  • That's what I expected. Good to hear. – JeremyK Oct 11 '15 at 22:48
  • To clarify, I have no errors with which to troubleshoot, but the value still does not appear in the client. – Bren Oct 11 '15 at 22:49
  • Create a new question - create a [mvce] focusing on the issue ( change 'results' to just return a json object (no other code), and ask how to use this results object as a parameter passed to fixedDisplay. Include code for fixedDisplay. – JeremyK Oct 11 '15 at 22:58
  • Thanks. Would fixedDisplay have anything to do with this though? I removed that and the issue remains – Bren Oct 11 '15 at 23:03
  • ok sorry I misunderstood. Take a look here: http://meteorpad.com/pad/otDtGaXuebHsjZ8dq/helpers – JeremyK Oct 11 '15 at 23:11
  • Can you check that the objects you are fetching in collections (up to `targetData`) are correctly defined when calling in JavaScript? – Kyll Oct 11 '15 at 23:12
  • @JeremyK, odd, you matched exactly what I have but I still get nothing. It's like it's just not recognizing the code `UI._globalHelpers` as valid. – Bren Oct 11 '15 at 23:21
  • @Kyll, confirmed, all are defined. `console.log` within the `peFy1` function returns value for each. – Bren Oct 11 '15 at 23:28
  • Can you try writing up a MeteorPad showing your issue in a reproducible way? – Kyll Oct 11 '15 at 23:31
  • Ok the other way to do it is make your global helper a normal (global) function. Then call it and return it's return value as your global helper. When you need it from JavaScript, call the (inner) ha function directly. – JeremyK Oct 11 '15 at 23:31
  • Much appreciated @JeremyK, I had seen that recommendation to someone else's post in Meteor Forums, but don't know how to implement. – Bren Oct 11 '15 at 23:38

1 Answers1

0

Your use of UI._globalHelpers.results().peFy1 looks correct syntactically.

However as an alternative option that sidesteps the Meteor (UI._globalHelpers) api, create a standard JavaScript function like this:

getResults = function(){
  var valuationId = this._id;
  var valuation = Valuations.findOne({_id: valuationId});
  var targetId = this.targetId;
  var targetTicker =     Companies.findOne({_id:targetId}).ticker;
  console.log('targetId: ' + targetId);
  console.log(Companies.findOne({_id:targetId})),
  var targetData = CompaniesData.findOne({ticker: targetTicker});
  return {
        peFy1: targetData.epsFy1 * valuation.PriceEarningsFy1,
        peFy2: targetData.epsFy2 * valuation.priceEarningsFy2
        }
};
Template.registerHelper('results',function(){
  return getResults();
});

Use results helper in templates and getResults function in JavaScript.

JeremyK
  • 3,240
  • 1
  • 11
  • 24
  • I know this is a very basic question, but where are you putting the `getResults` code? Right now, I have `Template.registerHelper('results')` in a `client/lib` folder. Can I just drop the new block in right above that? – Bren Oct 12 '15 at 00:12
  • Thanks. I've replicated this exactly point-for-point, but still not getting values and also now getting `Cannot read property 'ticker' of undefined` error. Likely more a function of my inexperience, will need to dig in a bit and see if I can work through it. Thanks. – Bren Oct 12 '15 at 02:11
  • Well that's an easy one. It's telling you that the expression to the left of .ticker (i.e. Companies.findOne({_id:targetId}) ) is undefined. or in other words, there is no document with that _id value in the Companies collection. – JeremyK Oct 12 '15 at 02:21
  • I see that, but it's the same expression I was using earlier which actually worked. The document is there. – Bren Oct 12 '15 at 02:35
  • Just to make sure, add the two extra lines I edited in above (console.log lines) and check it logs what you expect. That error, is it thrown from that line in the traceback? – JeremyK Oct 12 '15 at 02:43
  • Going to pick it up in the morning. Had tried what you suggested with no luck. But I think I might be getting something if I change findOne() to just find() for targetTicker. Will check back, thanks. – Bren Oct 12 '15 at 03:05
  • All set, my problem was 1) needed to declare `valuationId` and `targetId` in the template JS, not directly in the `getResults` and 2) then properly pass arguments. Thanks for your patience, posted working code in original post. – Bren Oct 12 '15 at 15:42