dynamic model on remote salesforce org

  • 1
  • Question
  • Updated 1 year ago
  • Acknowledged
  • (Edited)
I'm trying to dynamically build a series of models on external salesforce data sources. What do I need to pass to the model definition to get the model to load properly? Apparently giving skuid the dataSourceTypeName and dataSourceName is not enough. The model isn't getting the dataSource properly.

Any ideas?

Here's the relevant code:
var buildModel = function (n) {
    var model = new skuid.model.Model();
    model.dataSourceTypeName = "salesforce";
    model.dataSourceName = n;
    model.objectName = "Patient_Case__c";
    model.id = n;
    model.type = 'aggregate';
    model.isAggregate = true;
    model.groupByMethod = 'simple';
    model.groupByFields = [
        {id: "Positive_Pregnancy_Test__c", name: 'testresult'}
    ];
    model.fields = [
        {id: 'Id', name: 'countId', function:'COUNT'},
        {id: 'Positive_Pregnancy_Test__c', name: 'testresult', groupable: true}
    ];
    return model.initialize().register();
};

$.each(loopArray,function(i,name){
   modelsToQuery.push(buildModel(name));
});
$.when(skuid.model.load(modelsToQuery)).then(function(){
    
   //The models have no data!
    dfd.resolve();
});
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb

Posted 1 year ago

  • 1
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
9.5.8, if that matters? I'm in the process of upgrading to 9.5.10
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
bump
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Try setting just model.datasourceName instead of model.dataSourceTypeName and model.dataSourceName. For example, I have a datasource looking at another salesforce org called "RolodexSFOrg" and 

var model = new skuid.model.Model();    
model.dataSourceName = "RolodexSFOrg";
model.objectName = "Account";
model.id = "AccountModel";
model.type = 'aggregate';
model.isAggregate = true;
....

seemed like it worked.

Thanks!
(Edited)
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
We'll try it out! Thanks.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Hmm. It still doesn't seem to be working for us.

When we call .load() on an array of two models that were generated this way, here is the data in the request:
[
  {
    "id": "Lakeland",
    "objectName": "Patient_Case__c",
    "type": "aggregate",
    "groupByMethod": "simple",
    "fields": [
      {
        "id": "Id",
        "name": "countId",
        "function": "COUNT"
      },
      {
        "id": "Positive_Pregnancy_Test__c",
        "name": "testresult"
      }
    ],
    "groupByFields": [
      {
        "id": "Positive_Pregnancy_Test__c",
        "name": "testresult"
      }
    ],
    "conditions": [
      {
        "type": "fieldvalue",
        "field": "Case_Type__c",
        "value": "Pregnancy",
        "operator": "=",
        "encloseValueInQuotes": true
      },
      {
        "type": "fieldvalue",
        "field": "HasCompleteAppointment__c",
        "value": "0",
        "operator": "gt",
        "encloseValueInQuotes": false
      },
      {
        "type": "fieldvalue",
        "field": "First_Complete_Interaction_Date__c",
        "value": "2017-07-01T05:00:00.000Z",
        "inactive": false,
        "operator": "gte",
        "encloseValueInQuotes": false
      },
      {
        "type": "fieldvalue",
        "field": "First_Complete_Interaction_Date__c",
        "value": "2017-08-02T05:00:00.000Z",
        "inactive": false,
        "operator": "lte",
        "encloseValueInQuotes": false
      }
    ]
  },
  {
    "id": "Rochester",
    "objectName": "Patient_Case__c",
    "type": "aggregate",
    "groupByMethod": "simple",
    "fields": [
      {
        "id": "Id",
        "name": "countId",
        "function": "COUNT"
      },
      {
        "id": "Positive_Pregnancy_Test__c",
        "name": "testresult"
      }
    ],
    "groupByFields": [
      {
        "id": "Positive_Pregnancy_Test__c",
        "name": "testresult"
      }
    ],
    "conditions": [
      {
        "type": "fieldvalue",
        "field": "Case_Type__c",
        "value": "Pregnancy",
        "operator": "=",
        "encloseValueInQuotes": true
      },
      {
        "type": "fieldvalue",
        "field": "HasCompleteAppointment__c",
        "value": "0",
        "operator": "gt",
        "encloseValueInQuotes": false
      },
      {
        "type": "fieldvalue",
        "field": "First_Complete_Interaction_Date__c",
        "value": "2017-07-01T05:00:00.000Z",
        "inactive": false,
        "operator": "gte",
        "encloseValueInQuotes": false
      },
      {
        "type": "fieldvalue",
        "field": "First_Complete_Interaction_Date__c",
        "value": "2017-08-02T05:00:00.000Z",
        "inactive": false,
        "operator": "lte",
        "encloseValueInQuotes": false
      }
    ]
  } 
]

The models return empty. It's not actually reaching out to the data source to get any data, as far as I can tell.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Also, the models that we're creating have the accessible property set to false.
I don't see the 'accessible' property in the skuid.model.Model docs. What does this mean? Manually setting it to true doesn't change anything.
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
I'm not totally positive what the accessible property means for models, but I'm guessing it's similar to the accessible property on fields. I think it's based on if the current user has access to that model (object?) based on Salesforce permissions 
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Matt,

Hmm, I'm still not able to see the issue that you do. I'm able to create a model and get it to return data from an external Salesforce org (I'm checking for data at the end of the snippet and in the console, on the page, and am able to see that the model has data rows). Would you mind trying to pull in a standard object, and seeing if it works for you? I'm testing on 9.5.10, by the way:

(function($S, $){        var buildModel = function (n) {    var model = new skuid.model.Model();    model.dataSourceName = n;    model.objectName = "Account";    model.id = n;    model.type = 'aggregate';    model.isAggregate = true;    model.groupByMethod = 'simple';    model.groupByFields = [        {id: "Industry", name: 'testresult'}    ];    model.fields = [        {id: 'Id', name: 'countId', function:'COUNT'},        {id: 'Industry', name: 'testresult', groupable: true}    ];    return model.initialize().register();};var loopArray = ["External-SF-Org"];var modelsToQuery = [];$.each(loopArray,function(i,name){   modelsToQuery.push(buildModel(name));});$.when(skuid.model.load(modelsToQuery)).then(function(){   //The models have no data!   //dfd.resolve();        var sf = skuid.model.getModel("External-SF-Org");    console.log("sf ",sf);}); })(skuid, skuid.$);
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Amy,

Well, this is interesting.

I can get data using a modified version of your script to build models on the standard Accounts object.

I can get data from my custom objects when I build the models in the skuid builder.

I can't get data from my custom objects when I build the models in javascript.

What's going on here? Is there some kind of permissions issue?



Interestingly, when I run your script, I get data in the models but I also get this crazy console output:
(CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) extensions::lastError:82: Uncaught TypeError: Cannot convert undefined or null to object{TypeError: Cannot convert undefined or null to object
    at Object.clear (extensions::lastError:82:23)
    at handleResponse (extensions::sendRequest:77:15)}
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
skuid__ui?page=TestReport_Dynamic_testStandard:1 Error in event handler for (unknown): TypeError: Cannot convert undefined or null to object
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
extensions::lastError:82 Uncaught TypeError: Cannot convert undefined or null to object
    at Object.clear (extensions::lastError:82:23)
    at dispatchOnDisconnect (extensions::messaging:328:19)
clear @ extensions::lastError:82
dispatchOnDisconnect @ extensions::messaging:328
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
skuid__ui?page=TestReport_Dynamic_testStandard:1 Error in event handler for (unknown): TypeError: Cannot convert undefined or null to object
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
extensions::lastError:82 Uncaught TypeError: Cannot convert undefined or null to object
    at Object.clear (extensions::lastError:82:23)
    at dispatchOnDisconnect (extensions::messaging:328:19)
clear @ extensions::lastError:82
dispatchOnDisconnect @ extensions::messaging:328
extensions::extension:10 Uncaught Natives disabled
(anonymous) @ extensions::extension:10
2 skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) extensions::lastError:82: Uncaught TypeError: Cannot convert undefined or null to object{TypeError: Cannot convert undefined or null to object
    at Object.clear (extensions::lastError:82:23)
    at handleResponse (extensions::sendRequest:77:15)}
skuid__ui:243
2 skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) Lazy require of extension.binding did not set the binding field
skuid__ui?page=TestReport_Dynamic_testStandard:1 (CONTENT_SCRIPT context for bmnlcjabgnpnenekpadlanbbkooimhnj) extensions::lastError:82: Uncaught TypeError: Cannot convert undefined or null to object{TypeError: Cannot convert undefined or null to object
    at Object.clear (extensions::lastError:82:23)
    at handleResponse (extensions::sendRequest:77:15)}

I don't think all that has anything to do with why my code isn't working, but you never know...
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Hmm, I think there's a few different things going on here. It turns out there's an issue on your version of Skuid (Brooklyn Update 1) where dynamic models don't work unless there's a declarative model defined on the page. That seems like where your long error is coming from, but what's weird is that you can see data from standard objects (I'd expect you to not be able to pull in anything without a model on the page). I also saw that error when I was trying to create a model on a datasource that didn't exist in that org. Let me recap:

1. If I have only dynamic models on the page - the first pulling data from the current org and the second pulling data from another SF org, I'll get an error in the console (Uncaught TypeError: Cannot read property 'name' of undefined). The first model is created but empty and the second model isn't even created. If I try this on Skuid version Brooklyn Q2 or above, it works fine
2. If I have two dynamic models like above, and have one declarative model on the page pulling data from the external org, I'll still get an error on the page. The first created model, the one pulling data from the current org, is created but doesn't return any data. The other model isn't created.
3. If I have dynamic models like above and one declarative model that pulls data from the current org, the first model is created correctly, and the second model is created, but still empty. I get an error about not being able to find the field (I know it should be there). It's like it's looking in the current org instead of the external one.
4. If I have dynamic models like above and have two declarative models pulling data from the current org and external org, my external dynamic model still doesn't find the field.

In all four of those situations I had the external model looking at a custom object. If I changed to a standard object it loaded (on 3 and 4, on 2 it still failed to load) but it doesn't seem like it was returning the correct data.

To recap - Unfortunately, I think you'll have to upgrade to at least Brooklyn Q2 to get this working. Sorry I didn't catch the existing issue earlier, but I had a declarative model on my test page so I didn't notice. I listed the situations in detail because I'm still a little confused about how some of your models are loading. Do you have some declarative models on the page?
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Hey Skuid... this question is marked as "Answered"... but I still don't have working code. 
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Amy,

I have declarative models on the page. One model on the master page which pulls data from the current org, and three ui-only models. None of my dynamic models are on the current org, they are all external.

You're confident that this will work in Q2?
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Amy,

We upgraded to 10.0.3, and our models are still not returning data. All the dynamically created models return with assessible=false. They do not even generate a soql string.

Here is the full xml for the page. Any help would be greatly appreciated.
<skuidpage unsavedchangeswarning="yes" useviewportmeta="true">
    <models>
        <model id="PregnancyTestsDisplay" query="true" createrowifnonefound="false" datasource="Ui-Only" processonclient="true" unloadwarningifunsavedchanges="false">
            <fields>
                <field id="Center" displaytype="MULTIPICKLIST" label="Center" ogdisplaytype="TEXT" picklistsource="manual"/>
                <field id="positive" displaytype="DOUBLE" label="Positive Test Patients" ogdisplaytype="TEXT" datasource="salesforce" precision="9" scale="0"/>
                <field id="negative" displaytype="DOUBLE" label="Negative Test Patients" ogdisplaytype="TEXT" precision="9" scale="0"/>
                <field id="rate" displaytype="FORMULA" label="Rate" ogdisplaytype="TEXT" readonly="true" returntype="PERCENT" precision="9" scale="2">
                    <formula>{{positive}} / ({{positive}}+{{negative}}) * 100</formula>
                </field>
                <field id="date" displaytype="DATETIME" label="Date Filter" ogdisplaytype="TEXT"/>
                <field id="minTol" displaytype="DOUBLE" ogdisplaytype="TEXT" precision="9" scale="0" defaultvaluetype="fieldvalue" defaultValue="75" label="Minimum Tolerance"/>
                <field id="maxTol" displaytype="DOUBLE" label="Maximum Tolerance" ogdisplaytype="TEXT" precision="9" scale="0" defaultvaluetype="fieldvalue" defaultValue="90"/>
            </fields>
            <conditions/>
            <actions/>
        </model>
        <model id="Accounts" limit="" query="true" createrowifnonefound="false" datasource="salesforce" type="" sobject="Account" orderby="Name">
            <fields>
                <field id="Name"/>
                <field id="Active__c"/>
                <field id="Abortion_Hub_Classification__c"/>
                <field id="Id"/>
            </fields>
            <conditions>
                <condition type="fieldvalue" value="Yes" enclosevalueinquotes="true" field="Active__c" operator="="/>
                <condition type="fieldvalue" field="Abortion_Hub_Classification__c" operator="=" inactive="true" enclosevalueinquotes="true" name="__autofilter__Abortion_Hub_Classification__c" state="filterableoff" value=""/>
                <condition type="multiple" value="" field="Id" operator="in" enclosevalueinquotes="true" state="filterableoff" inactive="true" name="Id">
                    <values>
                        <value/>
                    </values>
                </condition>
            </conditions>
            <actions/>
        </model>
        <model id="Filters" query="true" createrowifnonefound="true" datasource="Ui-Only" processonclient="true" unloadwarningifunsavedchanges="false">
            <fields>
                <field id="Date" displaytype="DATETIME" label="Date Filter" ogdisplaytype="TEXT"/>
                <field id="centers" displaytype="MULTIPICKLIST" label="Centers" ogdisplaytype="TEXT" picklistsource="rowsinmodel" readonly="false" picklistmodel="Accounts" entryvalue="{{Name}}" snippet="accountsPicklist" defaultvaluetype="fieldvalue"/>
                <field id="start" displaytype="DATETIME" label="Start" ogdisplaytype="TEXT" defaultvaluetype="fieldvalue" defaultValue="LAST_MONTH"/>
                <field id="end" displaytype="DATETIME" label="End" ogdisplaytype="TEXT" defaultvaluetype="fieldvalue" defaultValue="THIS_MONTH"/>
            </fields>
            <conditions>
                <condition type="fieldvalue" field="Date" operator="gte" inactive="true" enclosevalueinquotes="false" name="__autofilter__start__Date" state="filterableoff" value=""/>
                <condition type="fieldvalue" field="Date" operator="lte" inactive="true" enclosevalueinquotes="false" name="__autofilter__end__Date" state="filterableoff" value=""/>
                <condition type="multiple" field="AccountFilter" operator="includes" inactive="true" enclosevalueinquotes="true" name="__autofilter__AccountFilter" state="filterableoff" value=""/>
            </conditions>
            <actions/>
        </model>
        <model id="Tolerance" query="true" createrowifnonefound="true" datasource="Ui-Only" processonclient="true" unloadwarningifunsavedchanges="false">
            <fields>
                <field id="minTol" displaytype="DOUBLE" label="Minimum Tolerance" ogdisplaytype="TEXT" precision="4" scale="0" defaultvaluetype="fieldvalue" defaultValue="75"/>
                <field id="maxTol" displaytype="DOUBLE" label="Maximum Tolerance" ogdisplaytype="TEXT" precision="4" scale="0" defaultvaluetype="fieldvalue" defaultValue="90"/>
            </fields>
            <conditions/>
            <actions>
                <action>
                    <actions>
                        <action type="updateRow" fieldmodel="PregnancyTestsDisplay" affectedrows="all" field="minTol" enclosevalueinquotes="false" value="{{$Model.Tolerance.data.0.minTol}}"/>
                        <action type="updateRow" fieldmodel="PregnancyTestsDisplay" affectedrows="all" field="maxTol" enclosevalueinquotes="false" value="{{$Model.Tolerance.data.0.maxTol}}"/>
                        <action type="custom" snippet="renderTable"/>
                    </actions>
                    <events>
                        <event>row.updated</event>
                    </events>
                    <fields>
                        <field>maxTol</field>
                        <field>minTol</field>
                    </fields>
                </action>
            </actions>
        </model>
    </models>
    <pageregioncontents>
        <pageregioncontent regionid="sk-1Bs3fO-269" uniqueid="sk-1ce-xa-85">
            <components>
                <pagetitle model="Filters" uniqueid="sk-1sHg4E-1163">
                    <maintitle>Positive Pregnancy Test Rate</maintitle>
                    <actions>
                        <action type="custom" label="Print" icon="fa-print" snippet="print" cssclass="no-print" uniqueid="sk-32RC7P-94"/>
                    </actions>
                    <renderconditions logictype="and"/>
                </pagetitle>
                <grid uniqueid="sk-1x4Y7f-411" columngutter="4px" rowgutter="4px">
                    <divisions>
                        <division behavior="fit" verticalalign="bottom">
                            <components>
                                <filterset model="Accounts" searchmethod="server" searchbox="false" uniqueid="sk-1-aI0m-326" instantfilters="true" emptysearchbehavior="query">
                                    <filters>
                                        <filter type="select" filteroffoptionlabel="All Classifications" createfilteroffoption="true" affectcookies="true" autocompthreshold="25" conditionsource="auto" labelmode="manual" conditionfield="Abortion_Hub_Classification__c" label="Classification"/>
                                    </filters>
                                    <searchfields/>
                                    <renderconditions logictype="and"/>
                                </filterset>
                            </components>
                        </division>
                        <division behavior="fit" verticalalign="bottom">
                            <components>
                                <basicfieldeditor showheader="true" showsavecancel="false" showerrorsinline="true" model="Filters" buttonposition="" uniqueid="customFilters" mode="edit" layout="above">
                                    <columns>
                                        <column width="33.3%">
                                            <sections>
                                                <section title="Section A" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field uniqueid="sk-32tXnX-427" id="centers" selectedlist="3" valuehalign="" type=""/>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                        <column width="33.3%">
                                            <sections>
                                                <section title="Section B" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field uniqueid="sk-32qbnY-321" id="start" valuehalign="" type=""/>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                        <column width="33.3%">
                                            <sections>
                                                <section title="New Section" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field uniqueid="sk-32qbnZ-322" id="end" valuehalign="" type=""/>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                    </columns>
                                </basicfieldeditor>
                            </components>
                        </division>
                        <division behavior="fit" verticalalign="bottom">
                            <components>
                                <buttonset model="Filters" uniqueid="GenerateButtonSet">
                                    <buttons>
                                        <button type="multi" label="Generate" snippet="generate" icon="sk-icon-generate-assets" uniqueid="sk-32RC7p-106">
                                            <actions>
                                                <action type="blockUI" message="Processing..."/>
                                                <action type="emptyModelData">
                                                    <models>
                                                        <model>PregnancyTestsDisplay</model>
                                                    </models>
                                                </action>
                                                <action type="custom" snippet="generate"/>
                                                <action type="blockUI" message="Done!" timeout="1000"/>
                                            </actions>
                                            <renderconditions logictype="and"/>
                                            <enableconditions logictype="and" message="Please select a date range to generate the report."/>
                                        </button>
                                    </buttons>
                                    <renderconditions logictype="and"/>
                                </buttonset>
                            </components>
                        </division>
                        <division behavior="flex" verticalalign="bottom" minwidth="300px" ratio="1">
                            <components>
                                <basicfieldeditor showheader="true" showsavecancel="false" showerrorsinline="true" model="Tolerance" buttonposition="" uniqueid="sk-1x4H9P-388" mode="read" layout="" cssclass="long-labels">
                                    <columns layoutmode="responsive" columngutter="4px" rowgutter="4px">
                                        <column ratio="1" minwidth="300px" behavior="flex" verticalalign="top">
                                            <sections>
                                                <section title="Section A" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field id="minTol" decimalplaces="" valuehalign="" type="" cssclass="below-tolerance" uniqueid="sk-32RC82-113"/>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                        <column ratio="1" minwidth="300px" behavior="flex">
                                            <sections>
                                                <section title="New Section" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field type="COMBO" valuehalign="" editmodebehavior="autopopup" cssclass="within-tolerance" uniqueid="sk-32RC8A-117">
                                                            <label>Within Tolerance</label>
                                                            <template>{{minTol}}-{{maxTol}}</template>
                                                        </field>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                        <column ratio="1" minwidth="300px" behavior="flex">
                                            <sections>
                                                <section title="Section B" collapsible="no" showheader="false">
                                                    <fields>
                                                        <field id="maxTol" decimalplaces="" valuehalign="" type="" cssclass="above-tolerance" uniqueid="sk-32RC8J-121"/>
                                                    </fields>
                                                </section>
                                            </sections>
                                        </column>
                                    </columns>
                                </basicfieldeditor>
                            </components>
                        </division>
                    </divisions>
                    <styles>
                        <styleitem type="background" bgtype="none"/>
                    </styles>
                </grid>
                <skootable showconditions="true" showsavecancel="false" showerrorsinline="true" searchmethod="client" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="false" model="PregnancyTestsDisplay" buttonposition="" mode="readonly" allowcolumnreordering="true" uniqueid="displayTable" emptysearchbehavior="query">
                    <fields>
                        <field id="Center" hideable="true" uniqueid="fi-1cuBd1-2728" valuehalign="" type="" maxdisplaycharacters="25"/>
                        <field id="positive" hideable="true" uniqueid="fi-1cuBd2-2729" decimalplaces="" valuehalign="" type="" columnwidth="">
                            <summaries>
                                <summary>sum</summary>
                            </summaries>
                        </field>
                        <field id="negative" hideable="true" uniqueid="fi-1cuBd2-2730" decimalplaces="" valuehalign="" type="">
                            <summaries>
                                <summary>sum</summary>
                            </summaries>
                        </field>
                        <field id="rate" hideable="true" uniqueid="fi-1cuBd2-2731" decimalplaces="2" valuehalign="" type="CUSTOM" snippet="renderWithTolerance">
                            <summaries>
                                <summary>avg</summary>
                            </summaries>
                            <renderconditions logictype="and" onhidedatabehavior="keep"/>
                            <enableconditions/>
                        </field>
                    </fields>
                    <rowactions/>
                    <massactions usefirstitemasdefault="true"/>
                    <views>
                        <view type="standard"/>
                    </views>
                    <actions defaultlabel="Global Actions" defaulticon="sk-icon-magic" usefirstitemasdefault="true"/>
                    <filters/>
                    <searchfields/>
                </skootable>
                <skuidvis__chart model="PregnancyTestsDisplay" maintitle="Positive Pregnancy Test Rates" type="column" uniqueid="displayChart">
                    <dataaxes>
                        <axis id="axis1" minvalue="0" maxvalue="100"/>
                    </dataaxes>
                    <categoryaxes>
                        <axis id="categories" categorytype="field" field="Center"/>
                    </categoryaxes>
                    <serieslist>
                        <series valuefield="rate" splittype="none"/>
                        <series valuefield="minTol" splittype="template" type="line" splittemplate="Minimum Tolerance"/>
                        <series valuefield="maxTol" splittype="template" splittemplate="Maximum Tolerance" type="line"/>
                    </serieslist>
                    <colors>
                        <value>#31a5b7</value>
                        <value>red</value>
                        <value>orange</value>
                    </colors>
                    <legend layout="horizontal" halign="center" valign="bottom"/>
                    <renderconditions logictype="and">
                        <rendercondition type="fieldvalue" enclosevalueinquotes="true" fieldmodel="PregnancyTestsDisplay" sourcetype="modelproperty" nosourcerowbehavior="deactivate" sourceproperty="hasRows"/>
                    </renderconditions>
                </skuidvis__chart>
            </components>
        </pageregioncontent>
    </pageregioncontents>
    <components/>
    <resources>
        <labels/>
        <css>
            <cssitem location="staticresource" name="ciJavascript" cachelocation="false" url="" namespace="" content_type="application/zip" filepath="CI_Tolerance.css"/>
        </css>
        <javascript>
            <jsitem location="staticresource" name="ciJavascript" cachelocation="false" url="" namespace="" content_type="application/zip" filepath="CI_TestDynamicReport.js">var params = arguments[0],
$ = skuid.$;
</jsitem>
        </javascript>
    </resources>
</skuidpage>
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
And here is the javascript for the page:
//Test Dynamic Report - Pregnancy Test
(function (skuid){
//////////////////////////////////////////////
// Shortcuts & Global Variables //
//////////////////////////////////////////////
var $ = skuid.$;
//////////////////////////////////////////////
// Snippets //
//////////////////////////////////////////////
var snippets = {
'generate': function () {
var dfd = new $.Deferred();
        var filterModel = arguments[0].model,
            filterRow = filterModel && filterModel.getFirstRow(),
            start = filterRow && filterRow.start,
            end = filterRow && filterRow.end,
            filterCenters = filterRow && filterRow.centers,
            displayModel = skuid.$M('PregnancyTestsDisplay'),
            modelsToQuery = [],
            accounts = [];
            
        $.each(skuid.$M("ActiveAccounts").getRows(),function(i,row){
            accounts.push(row.Name);
        });
        var loopArray = filterCenters ? filterCenters.split(';') : accounts;
        var buildModel = function (n) {
            var model = new skuid.model.Model();
            model.dataSourceName = n;
            model.objectName = "Patient_Case__c";
            model.id = n;
            model.type = 'aggregate';
            model.isAggregate = true;
            model.groupByMethod = 'simple';
            model.groupByFields = [
                {id: "Positive_Pregnancy_Test__c", name: 'testresult'}
            ];
            model.fields = [
                {id: 'Id', name: 'countId', function:'COUNT'},
                {id: 'Positive_Pregnancy_Test__c', name: 'testresult', groupable: true}
            ];
            model.conditions = [
                {type: 'fieldvalue', field: 'Case_Type__c', operator: '=', value: 'Pregnancy', encloseValueInQuotes: true},
                {type: 'fieldvalue', field: 'HasCompleteAppointment__c', operator: '!=', value: '0', encloseValueInQuotes: false},
                {type: 'fieldvalue', field: 'First_Complete_Interaction_Date__c', operator: 'gte', value: start, inactive: !start, encloseValueInQuotes: false},
                {type: 'fieldvalue', field: 'First_Complete_Interaction_Date__c', operator: 'lte', value: end, inactive: !end, encloseValueInQuotes: false}
            ];
            return model.initialize().register();
        };
        loopArray.sort();
        $.each(loopArray,function(i,name){
           modelsToQuery.push(buildModel(name));
        });
        $.when(skuid.model.load(modelsToQuery)).then(function(){
            $.each(modelsToQuery,function(i,model){
                var rows = model.getRows();
                var positive, negative;
                var name = model.id;
                $.each(rows,function(i,row){
                    if (row.testresult){  
                        positive = row.countId;
                    } else {
                        negative = row.countId;
                    }
                });
                displayModel.createRow({
                    doAppend: true,
                    additionalConditions:[{field:"Center", value: name}, {field:"positive", value:positive}, {field:"negative", value: negative}]
                });
            });
            $('td:first-child,th:first-child').hide();
            dfd.resolve();
        });
        return dfd.promise();
},
'renderWithTolerance': function (field,value) {
if(value){
            //Compare value to minTol and maxTol
                var comparison,
                    toleranceModel = skuid.$M("Tolerance"),
                    toleranceRow = toleranceModel && toleranceModel.getFirstRow(),
                    minTol = (toleranceRow && toleranceRow.minTol) || 75,
                    maxTol = (toleranceRow && toleranceRow.maxTol) || 90;
                
                if (value > maxTol) {
                    comparison = 'above-tolerance';
                } else if (value < minTol) {
                    comparison = 'below-tolerance';
                } else {
                    comparison = 'within-tolerance';
                }
                
                field.element.addClass(comparison);
            }
            
        skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
},
    'renderTable': function () {
        if (skuid.$C('displayTable')) skuid.$C('displayTable').render();
        if (skuid.$C('displayChart')) skuid.$C('displayChart').render();
        skuid.$('td:first-child,th:first-child').hide();
    },
    'checkDateFilterValues': function(){
        var model = skuid.$M('Filters'),
            conditions = model && model.conditions;
        return (conditions && conditions[0].value && conditions[1].value) ? true : false;
    }
};
//////////////////////////////////////////////
// Register Snippets //
//////////////////////////////////////////////
$.each(snippets,function(name,func){ skuid.snippet.registerSnippet(name,func); });
})(skuid);
(Edited)
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Matt,

Thank you so much for providing this information, and sorry that I mistakenly thought that Q2 would fix it. I did some testing (earlier) and it seemed to work in Q2, but upon further investigating I found some issues with dynamically created external SF models even in Q2. One of the issues is that it seems like if I have a declarative model on the page that looks at the current org, and then a dynamically created model that looks at an external SF org, the dynamically created model isn't created properly and looks to the current org instead of the external org. I've notified the devs of this issue and will let you know when this is fixed in a future release. I plan on doing a little more research to see if there's a workaround, but I'm not too optimistic.

Thanks!
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Matt,

Thank you so much for providing this information, and sorry that I mistakenly thought that Q2 would fix it. I did some testing (earlier) and it seemed to work in Q2, but upon further investigating I found some issues with dynamically created external SF models even in Q2. One of the issues is that it seems like if I have a declarative model on the page that looks at the current org, and then a dynamically created model that looks at an external SF org, the dynamically created model isn't created properly and looks to the current org instead of the external org. I've notified the devs of this issue and will let you know when this is fixed in a future release. I plan on doing a little more research to see if there's a workaround, but I'm not too optimistic.

Thanks!
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Amy,

It appears that skuid isn't building the dataSource property of the model correctly when given the dataSourceName. I'm wondering if "manually" building the dataSource object in JavaScript from the right row in a model on the ExternalDataSource object would work?
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Well, so much for that attempt:



There's no way I can build a model to get the data source information in order to build it dynamically for my dynamic models. Apparently we can only query the data sources under the skuid header.
(Edited)
Photo of Amy Dewaal

Amy Dewaal, Official Rep

  • 8,200 Points 5k badge 2x thumb
Matt,

I've talked with the devs, and the only work around for this issue is to add a declarative model on your page that uses the datasource you want to use dynamically (you'll need more than one model if you want to pull from more than one datasource). Then, in the snippet, Skuid will be able to recognize the datasource you're trying to build a model on. As always, we'll let you know when this is fixed in a future release.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Ok. Thanks for your help, Amy.

It building models dynamically was out attempt to NOT have to build them manually in the builder, so the workaround doesn't help in this case. Please do keep us up to date as soon as this bug is fixed.