cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with returned JSON object

chrisokelly
Champ on-the-rise
Champ on-the-rise
I am trying to write a dashlet to display blog posts with a particular tag. I originally used just a repo-tier webscript to search for and display them (modified from the blog category search example) and a web-view dashlet to show them on dashboards, however this seemed inelegant and sometimes displayed http basic auth requests when it shoudn't have.
Obviously the first hurdle I came to was the search API not being root scoped for share dashlets. I realized I couldn't do the whole job with a single webscript, that I would need one on the repo-tier and another to handle the dashlet.

I modified my original web-script to return JSON instead, and it now returns valid (at least according to jsonlint) json. Here's what it returns if I hit the webscript URL -

{
    "nodes" : {"0":"workspace://SpacesStore/dc9d18c0-9c69-4256-8203-f246a760b6e9","1":"workspace://SpacesStore/d2afcbad-de5a-4eec-b421-b7b223b3fc5a"}
}

I followed quite a few tutorials to get to this stage, mostly from Jeff Potts. I especially found the most recent document one helpful, however it was for a single result, I think my issues arise from trying to return an object. Originally I was getting an issue from my dashlet when it got to the obj = eval('(' + json + ')'); step, it gave me an error that I was missing a ']', even though I never even opened any square braces. Other posts on stackoverflow led me to this being an issue with trying to eval() an object, so I tried to access the object as json.data, json.nodes and just plain json instead as well - all show as undefined and give an error on the next step when I attempt to .length the variable.

Here's the section of my dashlet's javascript to deal with the result -

    var json = remote.call("/someCo/blog/public?maxPosts=" + maxPosts);
    if (json.status == 200)
    {
        //obj = eval('(' + json + ')'); - issue with missing ']'
      obj = json.nodes;
    }
   logger.warn(obj);
   nodes=obj;
   logger.warn("Obj received of length " + nodes.length);
   var results = [], result;
   // Turn nodes into result objects
   for (var i = 0, j = nodes.length; i < j; i++)
   {
      // Create core object
      node = getNodeFromString(nodes[i]);
     // Cut the site name out of displaypath
      blogSite = node.displayPath.slice(20,node.displayPath.lastIndexOf("/"));
     // Get the Person node for the blog creator
     blogUser = people.getPerson(node.properties["cm:creator"]);
     blogContent = node.content.slice(0,350) + "…";
     result =
      {
      blogContent: blogContent,
        name: node.name,
        title: node.properties["cm:title"],
        createdByUser: blogUser.properties["cm:firstName"] + " " + blogUser.properties["cm:lastName"],
      createdByUserName: node.properties["cm:creator"],
      blogSite: blogSite,
      dateCreated: node.properties["cm:published"]
      };
   if (result.blogContent && result.name && result.title && result.createdByUser && result.createdByUserName && result.blogSite && result.dateCreated)
      {
      if (node.qnamePath.indexOf("cm:post") != -1 )
         {
         results.push(result);
         }
      else
         {
         logger.warn("Public Blog Post Dashlet - An item, nodeRef:" + node.nodeRef + ", has been assigned the public tag but is not a blog post (lacks cm:post in qnamePath). It has been ignored.");
         }
      }
   else
      {
      logger.warn("Public Blog Post Dashlet - An item, nodeRef:" + node.nodeRef + ", has been assigned the public tag but lacks one or more required properties. It is likely not a blog post and has been ignored.");
      }
   }

   model.resultset = results;
   model.title = title;
}

I'm not sure where I am going wrong here, does anything here stick out to anyone here more experienced than I?


EDIT:

Realized I was going about this the wrong way, wanting to do as much of the work on the data as possible in the dashlet webscript to reduce the size and complexity of the json response. I managed to order the JSON response into a keyless array instead of an object, which made eval() start working for me, but then I found I couldn't getNodeFromString(), along with several other functions, from the share-tier.

Eventually got this working by moving the loop in which I extract data from the scriptnode objects to the repo-tier, and returning the JSON like this -
{
    "nodes" :
      [
         {
         "blogContent" : "<p>Work Today<\/p>\n<p>Changed strategy with landing page - David Draper's blog, which John put me onto for the configuration to override Share's landing page after login, has instructions for defining an HTML page for landing. Unfortunately I have found that this does not work for the share dashboard-style pages as a rendering error occurs. An issue…",
         "name" : "post-1335855405519",
         "title" : "01\/05\/2012 - Chris",
         "createdByUser" : "Chris O'Kelly",
         "createdByUserName" : "ChrisO",
         "dateCreated" : "01/May/2012",
         "blogSite" : "it-intranet"
         },
         {
         "blogContent" : "<p><strong>Work Today<\/strong><\/p>\n<p>compiled Postgresql client 9.0 on docs<\/p>\n<p>Tested backup script - working fine now<\/p>\n<p>Modified backup script to output a gzipped tar rather than a folder<\/p>\n<p> <\/p>\n<p>Finished MTP Train the Trainer course, added positioning slant to login page, made minor styling changes as of last weeks meeting …",
         "name" : "post-1335218980072",
         "title" : "23\/04\/2012 - Chris",
         "createdByUser" : "Chris O'Kelly",
         "createdByUserName" : "ChrisO",
         "dateCreated" : "24/Apr/2012",
         "blogSite" : "it-intranet"
         }]
}

then handling it via -
    var json = remote.call("/someCo/blog/public?maxPosts=" + maxPosts);
    if (json.status == 200)
    {
        obj = eval('(' + json + ')');
    }
   var nodes=obj.nodes;
   logger.warn("Obj received of length " + nodes.length);
   model.userIsSiteManager = userIsSiteManager;
   model.resultset = nodes;
   model.title = title;

This works fine (Although now I am dealing with an unrelated issue adding configurability to the dashlet. Hopefully I'll figure this one out on my own too)
2 REPLIES 2

jpotts
World-Class Innovator
World-Class Innovator
Glad you got it working.

Jeff

chrisokelly
Champ on-the-rise
Champ on-the-rise
Thanks Jeff, you indirectly solved this for me Smiley Tongue