Please help with template's data context


#1

I’m building a visualization app where a user will open an empty chart and switch in companies as they choose, then run financial analytics on the company. The companies all currently reside in a collection and are global, they are not owned by any user and are not editable.

Using the Microscope example, “Chart” would equate to “Post” and “Analysis” would equate to “Comment”. These elements are working fine. For equal comparison, I could imagine comparing Company to a Microscope-provided list of images that a user could select from to add to their post.

I included the {{companyName}} field in the code below, but I need to access much more than that in the {{> CompanyFinancials}} template.

<template name="Chart">
    <div>
        <div>
            {{chartName}}
       </div>
       <div>
           {{companyName}}
       </div>
       <div>
           {{> CompanyFinancials}}
       </div>
       <div>
           {{#each analyses}}
               {{> Analysis}}
           {{/each}}
       </div>
    </div>
</template>

I have a form to update the Chart document with the companyTicker, and need to use that ticker to run Companies.findOne({ticker: “someticker”}) on the Companies collection. However, I can’t figure out how to “attach” this company to the Chart to access its data.

Chart document

{
    "_id": "HufMPhGGydAcDZJHu",
    "userId": "CgzumC9suWQLJEkXc",
    "chartName": "test",
    "companyTicker": "GE"
}

Company document:

{
    "_id": "wSjW97wcg6WhpWHiK",
    "ticker": "GE",
    "companyName": "General Electric"
}

I thought I could replicate what I did in Analysis but these are unique to the Chart, whereas the Company is not, so I don’t want to extend the Company document with the Chart ID.

I am able to access and display data the Companies collection in the Analysis template.

var selections = ["A", "B", "C"];

Template.Valuation.helpers({
    selectedCompanies: function() {
        return Companies.find({ticker: {$in: selections}})
    }
});

Does this need to be done separately on every template then? I see how the loop sets the data for each Analysis but I’m actually not sure how to do that for just one document.

Or can one template just pull data from more than one collection?

I included the router code below in case it can be handled there.

Router.route('/charts/:_id', {
    name: Chart,
    waitOn: function() {
        return [
            Meteor.subscribe(chart, this.params._id),
            Meteor.subscribe('analyses', this.params._id),
            Meteor.subscribe('companies')
        ];
    },
    data: function() {
        return Charts.findOne(this.params._id);
    }
});

I hope this is all clear, would appreciate any and all help. Thanks so much all.

Addendum:
I added the following to replicate what I did in Analysis:

Template.Chart.helpers({
    target: function() {
    return Companies.findOne({ticker: "someticker"})
    }
};

Still stuck though on how to tell the Chart template that this is the one it should pull data from. Thanks.


Clarity on template helpers
#2

Template can have 100 helpers to pull from 100 different collections with different search parameters.
If you are publishing all data to client it is no problem, fun start when you want to limit data transfered to client and make publications already joined.


#3

@shock, thanks for your note. I’m certainly trying to move away from overpublishing as I make progress on this app. But I still can’t see how to tell the template that it needs to use this helper. For instance, in the code, above the #each links to the helper. But I don’t need a loop in this new instance. Do I need to wrap the Chart template with something similar so it knows that it wants the “target” from the helper?


#4

something like {{ #with helperName }} {{/with}} if you want to specify it for block?
or you can also do {{ target.userID }} {{target.companyTicker }} ?


#5

Thank you! I first tried #with and had some luck, but it looked like it would get pretty messy trying to figure out exactly what to wrap. target.companyName works great for every field. I just didn’t realize I could use the helper directly in the reference. Thanks again.