1

I'm trying to get Tasks that belong to the current user when the page loads.

This code works and can easily be copied and pasted in your dev console for testing and it prints all to the console.log. A simplified version.

VF page

<apex:page controller ="TestController" standardStylesheets="false" applyHtmlTag="false" sideBar="false" showHeader="false">

    <script>
    window.$userId = "{!$User.Id}";
    var app = angular.module('MyApp',[]);

    app.controller('myController',['$scope',function($scope)
                                   {

                                       $scope.getTaskData = Visualforce.remoting.Manager.invokeAction(
                                           '{!$RemoteAction.TestController.getTasks}',
                                           window.$userId,
                                           function(result, event)
                                           {
                                               $scope.$apply(function() {
                                                   console.log(result);
                                               });
                                           });
                                   }]);




    </script>
    <div ng-app="MyApp">

        <div ng-controller="myController">

        </div>
    </div>
    <apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"/>
    <apex:includeScript value="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"/>
</apex:page>

Controller

global class TestController {    

    @RemoteAction
    global static List<Task> getTasks(String ownerId) {
          return  [SELECT Id, Subject, ActivityDate, Status FROM Task WHERE Owner.Id =:ownerId limit 200];
    }
}

But this code below doesn't, and it uses the same getTaskData call to the remote action. 99% of all the development so far has been in the static resource for the app. You can download it here, zip it up and add it to your static resources. Then add the VF page and controller below to see what is fully going on. Be sure to go into the app.js to change your namespace if you have one. And name the the static resource when it's zip to 'taskCalendar'.

This file line 30. When I call the Visualforce Remote Action it breaks the app. Not sure why.

Sorry the long post, but I'm desperate and have been working on this for 15 hours today.....

VF Page

<apex:page applyHtmlTag="true" applyBodyTag="false" docType="html-5.0" showHeader="true" standardStylesheets="false" sidebar="false" controller="TaskCalendarController2">

     <meta charset="utf-8"/>
     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
     <meta name="description" content=""/>
     <meta name="author" content=""/>
     <link rel="icon" href="favicon.png"/>

    <script>

        window.$userId = "{!$User.Id}";

    </script>

    <apex:remoteObjects >
        <!--
            Each proxy object is defined by an apex:remoteObjectModel tag. The name attribute is set to the API name of the SObject you want perform DML operations on.
            The jsShorthand attribute is set to the JavaScript object name used to instantiate it.
            The fields attribute is set to a comma-delimited list of SObjectFields you want to load.
        -->
        <apex:remoteObjectModel name="Task" fields="Id, Subject, ActivityDate, Status">
            <!--Each field you load in to your proxy object can re-mapped to a friendlier name -->
        </apex:remoteObjectModel>
        <apex:remoteObjectModel name="User" fields="Id, FirstName, LastName, Email"/>
        <apex:remoteObjectModel name="Account" fields="Id,Name,CreatedDate"/>
    </apex:remoteObjects>    


    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/bs/css/bootstrap.min.css')}"/>
    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/fa/css/font-awesome.min.css')}"/>
    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/css/ie10-viewport-bug-workaround.css')}"/>

    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/fc/fullcalendar.css')}"/>
    <link href="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/fc/fullcalendar.print.css')}" rel='stylesheet' media='print' />


    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/typeahead/typeahead.css')}"/>

    <apex:stylesheet value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/css/custom.css')}"/>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]--> 


    <body ng-app="taskCalendar" class="wcs">

               <!-- Begin page content -->
        <div class="content-wrapper" ng-view="ng-view">
        </div>

        <div class="footer">
          <div class="container-fluid">
            <p class="text-muted">&copy; TouchPointCRM</p>
          </div>
        </div> 


        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/js/jquery.min.js')}"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/bs/js/bootstrap.min.js')}"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/js/ie10-viewport-bug-workaround.js')}"/>

        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/fc/lib/moment.min.js')}"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/fc/fullcalendar.min.js')}"/>

        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/typeahead/handlebars.min.js')}"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/typeahead/typeahead.bundle.min.js')}"/>

        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/assets/js/custom_tc.js')}"/>

        <apex:includeScript value="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"/>
        <apex:includeScript value="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/app/app.js')}"/>
        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/app/task/task-entity.js')}"/>

        <apex:includeScript value="{!URLFOR($Resource.taskCalendar, 'taskCalendar/app/task/task-calendar-controller.js')}"/>

    </body>

</apex:page>

Controller

global class TaskCalendarController2 {    
    @RemoteAction
    global static List<Task> getTasks(String ownerId) {
          return  [SELECT Id, Subject, ActivityDate, Status FROM Task WHERE Owner.Id = :ownerId limit 200];
    }
}
  • So what is your question? Which part is not working properly? – Lance Shi Nov 2 '16 at 5:46
  • @LanceShi updated. – Tyler Zika Nov 2 '16 at 5:49
2

So the main problem is Merge fields only work in VF pages. If you check this line https://github.com/tylerzika/taskCalendar/blob/master/app/task/task-calendar-controller.js#L32

You have a merge field which when moved to static resource just evaluates to a string, whereas when you use in VF page , it actually renders a value.

So in VF page you can do something like

var remoteGetTask = '{!$RemoteAction.TestController.getTasks}';

And in the static resource file

$scope.getTaskData = function() {       
    Visualforce.remoting.Manager.invokeAction(
       remoteGetTask,
       window.$userId,
       function(result, event)
       {
           $scope.$apply(function() {
            console.log(result);
           });
       }
    );
}
| improve this answer | |
0

Have a look at ngRemote. It's a little tool that creates services for each remoteObjectModel you define on your Visualforce Page so it's not using RemoteAction but Visualforce RemoteObjects.

https://github.com/florianhoehn/ngRemote

| improve this answer | |
  • I don't think this will work for me. VF Remote Objects don't let you query for parent objects. I need to do that in order to look up the owner.id of the Task. – Tyler Zika Nov 2 '16 at 17:24
  • Ahem, so use OwnerId on Task? And for real parent fields you need, either a formula field on the sObject itself OR a second call which is both not ideal but it saves you writing apex. – Florian Hoehn Nov 11 '16 at 16:24
0

Instead of:

   $scope.getTaskData = Visualforce.remoting.Manager.invokeAction(

           '{!$RemoteAction.TestController.getTasks}',
           window.$userId,
           function(result, event)
           {
               $scope.$apply(function() {
                console.log(result);
               });
           }
    );

Have you tried:

$scope.getTaskData = function() {       
    Visualforce.remoting.Manager.invokeAction(
       '{!$RemoteAction.TestController.getTasks}',
       window.$userId,
       function(result, event)
       {
           $scope.$apply(function() {
            console.log(result);
           });
       }
    );
}
| improve this answer | |
0

Instead of using Visualforce.remoting.Manager.invokeAction to call a remote action in your JavaScript file, you could simply use:

window['TestController']['getTasks'](window.$userId, function (result) {
    console.log(result);
});

This would not break your code :) You could directly access the remote action through window object

| improve this answer | |

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.