0

I currently have an app part built with REST and Angular. The issue I am having is that I'm getting Page Not Found errors from users with slower connections. I was told that JSOM would be considerably faster but I can't seem to connect it with Angular.

This is what I currently have:

(function (angular) {
var BlogTitle = BlogURL;
    angular.module('blogPart', ['ngSanitize'])
      .controller('homeCtrl', ['$scope', function ($scope, $timeout) {
          BackgroundColor = "{'background-color':'" + BackgroundColor + "'}";
          $scope.BackgroundColor = BackgroundColor;
          $scope.PostLimit = PostLimit;
          var today = new Date();
          var getPostQuantity = PostLimit + 7;

          jQuery.ajax({
              url: BlogTitle + "/_api/web/lists/getbyTitle('Posts')/items?" +
                  "$select=ID,Title,Body,Author/Id,Author/Title,NumComments/Id,LikesCount,LikedBy/Name,PublishedDate&$orderby=PublishedDate desc" +
                  "&$expand=Author,NumComments,LikedBy" +
                  "&$filter=PublishedDate le datetime'" + today.toISOString() + "'" +
                  "&$top=" + getPostQuantity,
              type: "GET",
              headers: {
                  "accept": "application/json;odata=verbose",
              },
              success: function (data, status, jqXHR) {
                  //fill model
                  var postResults = data.d.results;
                  var items = [];
                  for (var i = 0; i < postResults.length; i++) {
                      var item = {
                          id: postResults[i].ID,
                          title: postResults[i].Title,
                          numComments: postResults[i].NumComments.Id,
                          commentsUrl: BlogURL + "/Lists/Posts/Post.aspx?ID=" + postResults[i].ID + "#comments",
                          userUrl: hostUrl + "/_layouts/15/userdisp.aspx?ID=" + postResults[i].Author.Id,
                          numLikes: likes,
                          liked: isliked
                      };
                      items.push(item);
                  }
                  //update ui
                  $scope.$apply(function () {
                      $scope.items = items;
                  });
                  Communica.Part.init();
              },
              error: function (jqXHR, status, message) {
                  $scope.$apply(function () {
                      $scope.error = "Error: " + message;
                  });
              }
          });
      }]);
(window.angular);

I have this for JSOM but and I can get the data but how do I connect it with Angular? I tried starting it like I did with REST and that does not work.

function execCrossDomainRequest() {
var context;
var factory;
var appContextSite;
var mylist;
context = new SP.ClientContext(appweburl);
factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostUrl);
this.web = appContextSite.get_web();
mylist = this.web.get_lists().getByTitle('Posts');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><RowLimit>10</RowLimit></View>');
var collListItem = mylist.getItems(camlQuery);
context.load(mylist);
context.load(collListItem);
context.executeQueryAsync(
     Function.createDelegate(this, successHandler),
     Function.createDelegate(this, errorHandler)
);

function successHandler() {
    var listItemInfo = '';
    var listItemEnumerator = collListItem.getEnumerator();
    var listTitle = mylist.get_title();
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        listItemInfo += "<li style='height: 20px;'>" + oListItem.get_item('Title') + "</li>";
        document.getElementById("message").innerHTML = '<h1>' + mylist.get_title() + '</h1><br />';
        document.getElementById("message").innerHTML += listItemInfo.toString();
    }
}
function errorHandler() {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
}
  • the 404 is not likely due to your API choice, and in any case I doubt the notion that JSOM is faster. I suspect the opposite is true. – Derek Gusoff Oct 10 '15 at 0:18
  • Why are you using jQuery.ajax inside angular? see my article about sharepoint and angularjs codeproject.com/Articles/1002526/SharePoint-and-Angularjs – Atish Dipongkor - MVP Oct 10 '15 at 4:19
  • You are only giving is part of the code. What's in the HTML? There is no loop for postResults and in the second block you are creating a HTML structure which should be done in the Angular View with an ng-repeat loop (like I presume you do with items in the first block) – Danny '365CSI' Engelman Oct 10 '15 at 7:43
  • the use of $scope.apply should also not be necessary, it is only required when other code touches the DOM. $scope.items=items (or just directly built that $scope.items in a loop is enough – Danny '365CSI' Engelman Oct 10 '15 at 7:54
  • How do I add HTML without it trying to render? – Christopher Oct 12 '15 at 13:07
0

In the script below assumes you are hard coding the SP.js file into the page/masterpage instead of using the on demand syntax (SP.SOD)

Try this first create a factory and make sure it is has the $q capability

 .factory('myRESTFactory',factory($q){return function(){
 var deferred=$q.defer();
 var context; 
 var factory;
 var appContextSite;
 var mylist;
 context = new SP.ClientContext(appweburl);     
 factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
 context.set_webRequestExecutorFactory(factory);
 appContextSite = new SP.AppContextSite(context, hostUrl);
 this.web = appContextSite.get_web();
 mylist =this.web.get_lists().getByTitle('Posts');
 var camlQuery = new SP.CamlQuery();
 camlQuery.set_viewXml('<View><RowLimit>10</RowLimit></View>');
 var collListItem=mylist.getItems(camlQuery);
 context.load(mylist);
 context.load(collListItem);
 context.executeQueryAsync(
     Function.createDelegate(this, function(){
           var listItemInfo = '';
           var listItemEnumerator = collListItem.getEnumerator();
           var listTitle = mylist.get_title();
           var listObject=[]
           while (listItemEnumerator.moveNext()) {
              var oListItem = listItemEnumerator.get_current();
              listObject.push(oListItem.get_properties())
           };
           deferred.resolve(listObject)
           }),
     Function.createDelegate(this,function(sender,args){
       deferred.reject(args.get_message())
     }));

return deferred.promise(); }})

Then call the function in this way in the angular controller after adding your dependancy to "myRESTFactory"

$scope.myListItems=myRESTFactory()
                     .then(function(successObj){
                             console.log(successObj)
                           },
                           function(errorObj){
                             console.log(errorObj)
                           })

hope this helps

SECOND NOTE:

Instead of using AJAX in the controller, use .service or .factory to make a $http() async call. it removes the clutter from your controller and is more Angular-esque

a good format for this is

 .service('myService',function($http,$q){
    return {
      myFunction:function(){
            var deferred=$q.defer();
            var xreq={} //some object with headers - incompletecode
            $http(xreq).success(function(obj){deferred.resolve(obj)})
                       .fail(function(err){deferred.reject(err)})
           return deferred.promise();
      }
    }
 })
| 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.