5

I am trying to hack together a Canvas App so I can understand the Publish/Subscribe Model. I have a VF page in a dev org calling a URL in a SFDC Prod Org (so it has HTPPS) that just displays another VF page. I can get the basic samples in the docs to work (re-size/alert for Chatter users) but I cannot for the life of me get the VF page to publish, and my other page to subscribe...I just get an error from the CanvasApp Page in the console saying

Uncaught precondition fail

EDIT: The Canvas docs suggest I need include a reference to Controller.js - but the links they provide go nowhere - anyone know if this is still true, and if so, where I can find it?

VF Page in Org Using Canvas App:

<apex:page >
<script type="text/javascript" src="/canvas/sdk/js/29.0/canvas-all.js"/>

<apex:canvasApp applicationName="pnctest1" height="800px" parameters="{p1:'value1',p2:'value2',p3:'value3'}"/>

 <script>
         Sfdc.canvas (function () { 

         Sfdc.canvas.client.publish(
         {name: 'pnc.testAction', payload: {}
         }); 
         });

   </script>
</apex:page>

VF Page in Org Hosting Canvas App:

<apex:page controller="oAuthSetupforZDM" cache="FALSE">

<script type="text/javascript" src="https://na15.salesforce.com/canvas/sdk/js/29.0/canvas-all.js"/>

 <script>
 var sJson = [Working JSON Request];
 var sr = JSON.parse(sJson);
 Sfdc.canvas (function () {
            Sfdc.canvas.client.resize(sr.client, {height : "225px"});

            Sfdc.canvas.client.subscribe({name : 'pnc.testAction', 
                                  onData : function (e) {
                                      }
                                  });
 });           
    </script>

</apex:page>
3

I did get this to work eventually....looks like the link to Controller.Js in the docs is broken - they sent me this link that does work

I added that js code into my calling VF page, and was then able to click a link on my originating VF page to trigger an event in the Canvas App to post back to Chatter in my Org the value from my event...

<apex:page >

<script type="text/javascript" src="/canvas/sdk/js/29.0/canvas-all.js"/>
<script>
(function(global) {
  var module = function() {

    function subscribe(event) {
      Sfdc.canvas.parent.subscribe(event)
    }

    function unsubscribe(event) {
      Sfdc.canvas.parent.unsubscribe(event)
    }

    function publish(event) {
      Sfdc.canvas.parent.publish(event)
    }

    function resize(size, target) {
      Sfdc.canvas.parent.resize(size, target)
    }
    return{subscribe:subscribe, unsubscribe:unsubscribe, publish:publish, resize:resize}
  }();

  global.Sfdc = global.Sfdc || {};
  global.Sfdc.canvas = global.Sfdc.canvas || {};
  global.Sfdc.canvas.controller = module
})(this);
</script>

<apex:canvasApp applicationName="pnctest1" height="800px" parameters="{p1:'value1',p2:'value2',p3:'value3'}"/>

<script>

        function testpayload (msg) { 

         Sfdc.canvas.controller.publish({
             name: 'pnc.testAction', 
             payload : {status : msg}
             }); 

         };

   </script>

<apex:form >
<apex:commandLink onclick="testpayload('Open')" value="Open" reRender="TestPanel"/><br/>
<apex:commandLink onclick="testpayload('Closed')" value="Closed" reRender="TestPanel"/>
<apex:outputPanel id="TestPanel">
</apex:outputPanel>
</apex:form>   
</apex:page>

And then in my Canvas App:

<apex:page controller="oAuthSetupforZDM" cache="FALSE">

<script type="text/javascript" src="https://na15.salesforce.com/canvas/sdk/js/29.0/canvas-all.js"/>

 <script>
  var sJson = [SignedRequestJSON];

 var sr = JSON.parse(sJson);

Sfdc.canvas(function() {
Sfdc.canvas.client.subscribe(sr.client,
{name : 'pnc.testAction', onData : function (data) {

var url = sr.context.links.chatterFeedsUrl+"/news/"+sr.context.user.userId+"/feed-items";
var body = {body : {messageSegments : [{type: "Text", text: "We are " + data.status}]}};
Sfdc.canvas.client.ajax(url,
{client : sr.client,
method: 'POST',
contentType: "application/json",
data: JSON.stringify(body),
success : function(data) {
if (201 === data.status) {
console.log('Success');
}
}
});

</script>

</apex:page>
2

As a note here, the Sfdc.canvas.parent.* methods are not supported for client use. Instead we expose the methods using Sfdc.canvas.controller.*

So for the code above to be supported by salesforce, you would need to:

  1. Add the controller.js file as a script tag in the VF page:

    <script type="text/javascript" src="/canvas/sdk/js/30.0/controller.js"/>
    
  2. Change the method calls to use Sfdc.canvas.controller.subscribe, Sfdc.canvas.controller.publish, Sfdc.canvas.controller.unsubscribe, and Sfdc.canvas.controller.resize where appropriate

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.