I've been having an issue with AJAX parsing a JSON Array from a webservice I'm creating. My front end is a simple ajax & jquery combo to display results returned from the webservice I'm creating.
I'm getting an error within Chrome's console stating "cannot read the length property of undefined" despite knowing that there are results from my database query.
After looking for an answer for days I still cannot figure out why I get the console error.
Thank you for any help! :)
function ajaxrequest(e)
{
var r = $('#region').val();
var t = $('#type').val();
console.log(r,t);
$.ajax('https://URL...../.../POI/POI_LOOKUP.php',
{ type: 'GET',
data: 'type='+t+'®ion='+r+'&format=json',
success: onSuccess }
);
}
function onSuccess(data,status,xmlHTTP)
{
var html = "<table><th>name</th><th>type</th><th>country</th><th>region</th>";
for(var i=0; i<data.length; i++)
{
html = html + '<tr><td>' + data[i].name + '</td>' + '<td>' + data[i].type + '</td>' + '<td>' + data[i].country + '</td>' + '<td>' + data[i].region + '</td></tr>';
}
html = html + '</table>';
$('#results').html(html);
console.log(data);
console.log(status);
}
Here is my PHP to search and return all results:
IF ($type == "any" && !isset($region)) /* Search DB for all types of POI for all regions*/
{
$statement = $conn->prepare("SELECT * FROM pointsofinterest;");
$statement->execute();
$row = $statement->fetch();
if ($row == false)
{
header("HTTP/1.1 204 No Content");
}
else
{
$allResults = array();
while($row != false)
{
$allResults[] = $row;
$row = $statement->fetch(PDO::FETCH_ASSOC);
}
echo json_encode($allResults);
}
}
Ideally you should pass back empty results, if there are no results, and let the Javascript decide what to do (display a nice friendly message to the user). I haven't tested this, it's just for guidance, be warned.
PHP
if ($type == "any" && !isset($region)) /* Search DB for all types of POI for all regions*/
{
$statement = $conn->prepare("SELECT * FROM pointsofinterest;");
$statement->execute();
$results = $statement->fetchAll();
if (count($results)!=0){
echo json_encode($results);
} else {
header("HTTP/1.1 204 No Content");
}
}
JAVASCRIPT
You may want to handle the 204 response separately: How to handle a 204 response in jquery ajax?. The code below assumes you may receive an empty JSON response.
function onSuccess(data,status,xmlHTTP)
{
if (data.length==0) {
alert("Friendly user message");
return;
}
var html = "<table><th>name</th><th>type</th><th>country</th><th>region</th>";
for(var i=0; i<data.length; i++)
{
html = html + '<tr><td>' + data[i].name + '</td>' + '<td>' + data[i].type + '</td>' + '<td>' + data[i].country + '</td>' + '<td>' + data[i].region + '</td></tr>';
}
html = html + '</table>';
$('#results').html(html);
console.log(data);
console.log(status);
}
Related
I have a Javascript ajax function that calls a PHP page to run a query and return an array of values which I then want to use to build a navigation list.
I can retrieve the results from the query, add them to an array and then encode them using json_encode but when they are returned to the ajax function I'm having problems extracting the values from the array and building the nav list.
Any help is very much appreciated.
My PHP Code is:
<?php
require_once("../includes/functions.inc");
$access_id = $_POST['access_id'];
$mysqli = new mysqli(DBHOST, DBUSER, DBPASS, DB);
if ($mysqli->connect_errno) {
error_log("Cannot connect to MySQL: " . $mysqli->connect_error);
return false;
}
$query = "SELECT nav_link, nav_icon, nav_name FROM tbl_nav WHERE access_id <= " . $access_id;
$result = mysqli_query($mysqli, $query);
$rows = array();
while ($r = mysqli_fetch_array($result)){
$rows[] = $r;
}
echo json_encode($rows);
My Javascript code is
$(function(){
$.ajax({
type: "POST",
url: 'php_files/user_process/left_nav_generate.php',
dataType: 'JSON',
data: {
access_id: sessionStorage.getItem('access_id')
},
success: function(data) {
var obj = JSON.parse(data);
var headerNavItem = '';
var navBarList = '';
var footerNavItem = '';
headerNavItem = '<ul class="navigation navigation-main navigation-accordion">';
headerNavItem += '<li><i class="icon-home"></i><span>Dashboard</span></li>';
headerNavItem += '<li class="navigation-divider"></li>';
for (var i in obj) {
navBarList = '<li><a href="' + data[i].nav_link;
navBarList += '"><i class="' + data[i].nav_icon;
navBarList += '"></i> <span>' + data[i].nav_name;
navBarList += '</span></a></li>';
}
footerNavItem = '</ul>';
document.getElementById('leftNav').innerHTML = headerNavItem + navBarList + footerNavItem;
}
});
});
You need to replace mysql_fetch_array with mysql_fetch_assoc since you will use each record as an object later, and make a few corrections in your javascript (I commented them):
$(function(){
$.ajax({
type: "POST",
url: 'ajax.php',
dataType: 'JSON',
data: {
access_id: sessionStorage.getItem('access_id')
},
success: function(data) {
var obj = data; // JSON.parse(data); -> is not needed
var headerNavItem = '';
var navBarList = '';
var footerNavItem = '';
headerNavItem = '<ul class="navigation navigation-main navigation-accordion">';
headerNavItem += '<li><i class="icon-home"></i><span>Dashboard</span></li>';
headerNavItem += '<li class="navigation-divider"></li>';
for (var i in obj) {
// added concatenation from the start
// otherwise your list will always have just one line
navBarList += '<li><a href="' + data[i].nav_link;
navBarList += '"><i class="' + data[i].nav_icon;
navBarList += '"></i> <span>' + data[i].nav_name;
navBarList += '</span></a></li>';
}
footerNavItem = '</ul>';
document.getElementById('leftNav').innerHTML = headerNavItem + navBarList + footerNavItem;
}
});
});
And as commented, to avoid SQL injection is a good practice to convert the id to integer (or whatever the type of the access_id field in database):
$access_id = (int)$_POST['access_id'];
According to u_mulder's comment: Your data argument is already a JSON so remove JSON.parse(data);.
navBarList = '<li><a href="' + data[i].nav_link; The navBarList variable restarts for every item every item in the for statement. Change it to navBarList += '<li><a href="' + data[i].nav_link;.
You can use a simple variable to build your HTML navigation list.
Something like this:
$(function() {
var obj = [{
"nav_link": "nav_link1",
"nav_icon": "nav_icon1",
"nav_name": "Name 1"
}, {
"nav_link": "nav_link2",
"nav_icon": "nav_icon2",
"nav_name": "Name 2"
}, {
"nav_link": "nav_link3",
"nav_icon": "nav_icon3",
"nav_name": "Name 3"
}];
var html = '<ul class="navigation navigation-main navigation-accordion">';
html += '<li><i class="icon-home"></i><span>Dashboard</span></li>';
html += '<li class="navigation-divider"></li>';
for (var i in obj) {
html += '<li><a href="';
html += obj[i].nav_link;
html += '"><i class="';
html += obj[i].nav_icon;
html += '"></i> <span>';
html += obj[i].nav_name;
html += '</span></a></li>';
}
html += '</ul>';
document.getElementById('leftNav').innerHTML = html;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="leftNav"></div>
Hope this helps.
I have written JavaScript which retrieves data and sets it into a series of tables as shown below.
$(function()
{
$.ajax(
{
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists(guid'9BBF789F-E5BA-449D-A595-BAA326E2C8FF')/Items?$expand=Category&$select=Id,Related_x0020_Working_x0020_PracId,Title,Reference,Policy_x0020_Type,Category/Title&$orderby=Category/Title asc",
type:"get",
headers: { "accept": "application/json;odata=verbose" },
success: function(dataObj)
{
//to uniquely identifiy the accordion.
var intCat = 0;
var arrPolicies = [];
var arrCategories = [];
//Get the policies and seperate out the categories from the returned REST call
for(var i =0; i < dataObj.d.results.length; i++)
{
var strCategory = dataObj.d.results[i].Category.Title;
arrPolicies.push({
"Id" : dataObj.d.results[i].Id,
"Title" : dataObj.d.results[i].Title,
"Category" : strCategory,
"Ref" : dataObj.d.results[i].Reference,
"PolicyType" : dataObj.d.results[i].Policy_x0020_Type,
"WorkingPracticeId" : dataObj.d.results[i].Related_x0020_Working_x0020_PracId
});
//setting category if not found
//in array
if(arrCategories.indexOf(strCategory) == -1)
{
//Add the category to the list...
arrCategories.push(strCategory);
}
}
//Output the menu to the screen for each category - one by one
arrCategories.forEach(function(varCategory)
{
var strCatIdentifier = "tblCategory_" + intCat;
var strCatImgIdentifier = "tblCategory_image_" + intCat;
var strCategoryInfo = "<table>"+
"<tbody>" +
"<tr>"+
"<td class='category'>"+
"<a href='javascript:ExpandCollapseRow(" + strCatIdentifier + ","+strCatImgIdentifier+")'>"+
"<img id='"+strCatImgIdentifier+"' src='" + _spPageContextInfo.webAbsoluteUrl + "/SiteAssets/Images/expand-16.png' alt='expand category'/>"+
"</a> "+
varCategory +
"</td>"+
"</tr>"+
"<tr><td>"+
"<table id='" + strCatIdentifier + "' class='indent hidden'>";
//looping through policies - add the details into the category table's cell
arrPolicies.forEach(function(varPolicy)
{
//checking the category attached to the policy is the same as what
//category it is on
if(varPolicy.Category == varCategory)
{
//checking to see if the
if(varPolicy.PolicyType == "Policy and Responsibility")
{
strCategoryInfo += "<tr>"+
"<td class='policy'>" +
"<a href='#'>"+
"<img src='"+_spPageContextInfo.webAbsoluteUrl+"/SiteAssets/Images/arrowicon.png' alt='View Document'/>"+
"</a>"
+ varPolicy.PolicyType + ": "+varPolicy.Ref +" - " + varPolicy.Title +
"</td>"+
"</tr>";
}
//If Working Practice - add in the sub-table (3rd level table) for attachments
if(varPolicy.PolicyType == "Working Practices")
{
var strCatWPIdentifier = "tblWorkingPractice" + varPolicy.Id;
var strCatWPImgIdentifier = "sub_level_image" + varPolicy.Id;
strCategoryInfo += "<tr>"+
"<td class='working_practice'>"+
"<a href='javascript:ExpandCollapseRow(" + strCatWPIdentifier + ","+strCatWPImgIdentifier+")'>"+
"<img id='"+strCatWPImgIdentifier+"' src='" + _spPageContextInfo.webAbsoluteUrl + "/SiteAssets/Images/expand-16.png' alt='expand working practice'/>"+
"</a> "+
varPolicy.PolicyType + " - " + varPolicy.Title+
"</td>"+
"</tr>";
var intAttachmentCount = 0;
//Build a table by looping through the policies array AGAIN and only use the policies where the Policy Type is 'Attachment' AND the 'WorkingPracticeID' is the same as the pilocy ID
arrPolicies.forEach(function(varWPAttachment)
{
if(varWPAttachment.WorkingPracticeId == varPolicy.Id && varWPAttachment.PolicyType == "Working Practice Attachment")
{
intAttachmentCount++;
strCategoryInfo += "<tr>"+
"<td>"+
"<table id='"+strCatWPIdentifier+"' class='indent hidden'>"+
"<tr>"+
"<td>"+
varWPAttachment.PolicyType +" - "+ varWPAttachment.Title+ " - " + varPolicy.Title+
"</td>"+
"</tr>"+
"</table>"+
"</td>"+
"</tr>";
}
});
if(intAttachmentCount == 0)
{
strCategoryInfo += "<tr>"+
"<td>"+
"<table id='"+strCatWPIdentifier+"' class='indent hidden'>"+
"<tr>"+
"<td>"+
"Sorry, no attachments found for this practice."+
"</td>"+
"</tr>"+
"</table>"+
"</td>"+
"</tr>";
}
}
}
});
//Close the 'Category details' table
strCategoryInfo += "</table>";
//Close the table for the category...
strCategoryInfo += "</td></tr>" +
"</tbody>"+
"</table>";
intCat++;
$('#divQualityFrameworkMenu').append(strCategoryInfo + "<br />");
});
},
error: function(error)
{
alert("Error");
}
});
});
I want to be able to organise them so that related data is grouped together ie Policies are above working practices.
How would I go about doing this
This seems pretty easy. After the first for (var d = 0; [...] ) loop, but before the arrCategories.forEach([...]), just sort arrPolicies to your choosing:
arrPolicies.sort(function(policy1, policy2) {
//Policies BEFORE Working Practicies:
if (policy1.PolicyType === "Policies and Responsibilities" && policy2.PolicyType === "Working Practices") {
return -1;
}
//Working Practicies AFTER Policies:
if (policy1.PolicyType === "Working Practices" && policy2.PolicyType === "Policies and Responsibilities") {
return 1;
}
//[Include any other orderings you might have...]
//If you've reached the end here, then you must not care about the ordering of these policies, so just make them "equal":
return 0;
});
I'm using Facebook Javascript SDK and FB.api. I read public pages' posts and wanted to show it on my website. So I made the call with FB.api and got the response. But while I try to show them by Facebook Embed System it just didn't show up.
Here is my code
FB.api("/" + PageId + "/posts",
{
access_token: getCookie("access_token"),
since: From,
until: To,
fields: "id,likes.summary(true).limit(0),comments.summary(true).limit(0),shares,link",
limit: LoadLimit,
date_format: "U",
},
function (res) {
$("#load_post").attr("disabled", false).attr("value", "Load Posts");
if (typeof res.error === 'undefined') {
if (res.data.length > 0) {
for (var i = 1; i <= res.data.length; i++) {
var NewData = res.data[i - 1];
var Id = NewData.id.split("_")[1];
var CreatedTime = NewData.created_time;
var Likes = NewData.likes.summary.total_count;
var Comment = NewData.comments.summary.total_count;
var Share = 0;
var Link = NewData.link;
if (typeof NewData.shares !== 'undefined') {
Share = NewData.shares.count;
}
var Data = "";
Data += "<tr>";
Data += "<td>" + i + "</td>";
Data += "<td><div id='" + Id + "' class='fb-post' data-href='" + Link + "' data-width='350'></div></td>";
Data += "<td>" + CreatedTime + "</td>";
Data += "<td>" + Likes + "</td>";
Data += "<td>" + Comment + "</td>";
Data += "<td>" + Share + "</td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "</tr>";
$("#data_area").append(Data);
FB.XFBML.parse(document.getElementById(Id));
}
} else {
alert("No data found.");
}
} else {
alert("Error occured.\n" + res.error.message);
}
});
Even I tried "FB.XFBML.parse" but lately checking the documentation I found that it has no effect on Embed Post.
I checked the console and found no error or something.
Please help me out.
I've recently been trying to repeat a jQuery AJAX request every two seconds. PLEASE NOTE: I've looked at the other questions on SO and not of them seem to apply to my situation, i've also looked at the documentation.
Snippet:
else if (text == "load") {
$(".response").text("working!");
var traffic = function load() {
$.ajax({url:"load.php",success:function(result){
var obj = jQuery.parseJSON(result);
var ids = obj.map(function(el) {
return "<tr><td>" + el.id + "</td><td>" + el.ip + "</td><td>" + el.proxyip + "</td><td>" + el.ping + "</td><td>" + el.time + "</td></tr>";
});
$(".response").html("<table><tr><td><strong>ID</strong></td><td><strong>IPs</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr>" + ids + "</table>");
}});
};
var trafficInterval = setInterval(traffic, 2000);
To cancle the timeout, i check to see if the text is not equal to "load", if it isnt equal to load, i cancle the timeout
else {
$(".response").text("'" + badCommand + "'" +" is not a valid command, type 'help' for a list of commands.");
clearInterval(trafficInterval);
}
HOWEVER, when i change the input of the textfield, the table will still load every two seconds, the timeout hasn't been cancled and i can't seem to see why.
Here's the whole function for people wondering
$("textarea").keyup(function(){
var text = $(this).val();
$(".log").text(text);
// Commands
if (text != "") {
var badCommand = $("textarea").val();
if (text == "help") {
$(".response").html("Commands:<br/><span class='indent'>traffic -url|all</span><span class='indent'>google #search term</span><span class='indent'>youtube #search term</span><span class='indent'>portfolio</span>")
} else if (text == "traffic") {
$(".response").html('Live traffic from:<br/><table><tr><td><strong>IP</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr><?php try { $db = new PDO("mysql:host=$mysql_host;dbname=$mysql_db", $mysql_user, $mysql_pass); $sql = "SELECT * FROM traffic ORDER BY id DESC LIMIT 50"; foreach ($db->query($sql) as $row) { echo "<tr>"; echo "<td class='details'>" . $row["ip"] . "</td>"; echo "<td class='details'>" . $row["proxyip"] . "</td>"; echo "<td class='details'>" . $row["ping"] . "</td>"; echo "<td class='details'>" . $row["time"] . "</td>"; echo "</tr>"; } $db = null; } catch(PDOException $e) { $e->getMessage(); } ?></tr></table>');
} else if (text == "load") {
$(".response").text("working!");
var traffic = function load() {
$.ajax({url:"load.php",success:function(result){
var obj = jQuery.parseJSON(result);
var ids = obj.map(function(el) {
return "<tr><td>" + el.id + "</td><td>" + el.ip + "</td><td>" + el.proxyip + "</td><td>" + el.ping + "</td><td>" + el.time + "</td></tr>";
});
$(".response").html("<table><tr><td><strong>ID</strong></td><td><strong>IPs</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr>" + ids + "</table>");
}});
};
var trafficInterval = setInterval(traffic, 2000);
} else {
$(".response").text("'" + badCommand + "'" +" is not a valid command, type 'help' for a list of commands.");
clearInterval(trafficInterval);
}
}
if (text == "") {
var noCommand = $("textarea").val();
$(".response").text(" ");
}
// End Commands
});
FYI:
Putting the clearInterval(); AFTER the code stops it from working,
Putting the clearInterval(); BEFORE the code does nothing.
The clearInterval(trafficInterval); MUST be working because if i place it at the end of the first function, nothing happens when i type "load"
It's not the timer either, i tried it instead to automatically update whenever the mouse is moved and the exact same thing happens...
This is a scoping issue. The interval needs to be outside the scope of the event handler call:
var trafficInterval = null;
$("textarea").keyup(function(){
var text = $(this).val();
$(".log").text(text);
// Commands
if (text != "") {
var badCommand = $("textarea").val();
if (text == "help") {
$(".response").html("Commands:<br/><span class='indent'>traffic -url|all</span><span class='indent'>google #search term</span><span class='indent'>youtube #search term</span><span class='indent'>portfolio</span>")
} else if (text == "traffic") {
$(".response").html('');
} else if (text == "load") {
$(".response").text("working!");
var traffic = function load() {
$.ajax({url:"load.php",success:function(result){
var obj = jQuery.parseJSON(result);
var ids = obj.map(function(el) {
return "<tr><td>" + el.id + "</td><td>" + el.ip + "</td><td>" + el.proxyip + "</td><td>" + el.ping + "</td><td>" + el.time + "</td></tr>";
});
$(".response").html("<table><tr><td><strong>ID</strong></td><td><strong>IPs</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr>" + ids + "</table>");
}});
};
trafficInterval = setInterval(traffic, 2000);
} else {
$(".response").text("'" + badCommand + "'" +" is not a valid command, type 'help' for a list of commands.");
clearInterval(trafficInterval);
}
}
if (text == "") {
var noCommand = $("textarea").val();
$(".response").text(" ");
}
// End Commands
});
See fiddle # http://jsfiddle.net/sLooj4on/ (can see polling fail in dev tools, stops when text is removed from input)
It's hard to tell without looking at the rest of the code, but your trafficInterval variable could be out of scope. Try initializing outside of the if/else statement
trafficInterval is only defined within the if statement. You're trying to clear it in the wrong scope. I still lack a bit of context here but you can try this:
var trafficInterval;
$("textarea").keyup(function() {
var text = $(this).val();
$(".log").text(text);
// Commands
if (text != "") {
var badCommand = $("textarea").val();
if (text == "help") {
$(".response").html("Commands:<br/><span class='indent'>traffic -url|all</span><span class='indent'>google #search term</span><span class='indent'>youtube #search term</span><span class='indent'>portfolio</span>")
} else if (text == "traffic") {
$(".response").html('Live traffic from:<br/><table><tr><td><strong>IP</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr><?php try { $db = new PDO("mysql:host=$mysql_host;dbname=$mysql_db", $mysql_user, $mysql_pass); $sql = "SELECT * FROM traffic ORDER BY id DESC LIMIT 50"; foreach ($db->query($sql) as $row) { echo "<tr>"; echo "<td class='
details '>" . $row["ip"] . "</td>"; echo "<td class='
details '>" . $row["proxyip"] . "</td>"; echo "<td class='
details '>" . $row["ping"] . "</td>"; echo "<td class='
details '>" . $row["time"] . "</td>"; echo "</tr>"; } $db = null; } catch(PDOException $e) { $e->getMessage(); } ?></tr></table>');
} else if (text == "load") {
$(".response").text("working!");
var traffic = function load() {
$.ajax({
url: "load.php",
success: function(result) {
var obj = jQuery.parseJSON(result);
var ids = obj.map(function(el) {
return "<tr><td>" + el.id + "</td><td>" + el.ip + "</td><td>" + el.proxyip + "</td><td>" + el.ping + "</td><td>" + el.time + "</td></tr>";
});
$(".response").html("<table><tr><td><strong>ID</strong></td><td><strong>IPs</strong></td><td><strong>Proxy IP</strong></td><td><strong>Ping</strong></td><td><strong>Time</strong></td></tr>" + ids + "</table>");
}
});
};
trafficInterval = setInterval(traffic, 2000);
} else {
$(".response").text("'" + badCommand + "'" + " is not a valid command, type 'help' for a list of commands.");
clearInterval(trafficInterval);
}
}
if (text == "") {
var noCommand = $("textarea").val();
$(".response").text(" ");
}
// End Commands
Move the variable declaration
var trafficInterval = null;
before the keyup eventhandler (to move it to the outside scope). See working, stripped down example here:
http://jsbin.com/yitiquwoce/1/
I am trying to use the javascript object model to retrieve a list of users/groups for a list and their permissions at the list level. So far I have this which returns a member object but I cant get any information about the member. When I try to use rAssignment.get_member().get_id(), or rAssignment.get_member().get_title() I get an error.
//Get List Permissions
function getListPerms() {
var clientContext = new SP.ClientContext();
var siteColl = clientContext.get_site();
var site = clientContext.get_web();
listSecurableObject = site.get_lists().getByTitle($("[name='ListSlct']").val());
listRoleAssignments = listSecurableObject.get_roleAssignments();
clientContext.load(listRoleAssignments);
clientContext.executeQueryAsync(Function.createDelegate(this, this.getListPerms_onQuerySucceeded),Function.createDelegate(this, this.getListPerms_onQueryFailed));
}
function getListPerms_onQuerySucceeded() {
var listPerms="";
listPerms += '<table border="1">';
listPerms += '<tr>';
listPerms += '<td align="center">ID</td>';
listPerms += '</tr>';
var listPermsEnumerator = this.listRoleAssignments.getEnumerator();
while (listPermsEnumerator.moveNext()) {
var rAssignment = listPermsEnumerator.get_current();
listPerms += '<tr>';
listPerms += '<td align="center">' + rAssignment.get_member() + '</td>';
listPerms += '</tr>';
}
listPerms += '</table>';
document.getElementById('listPermsTable').innerHTML = listPerms;
}
function getListPerms_onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
Try changing your clientContext.load() function call as follows:
clientContext.load(listSecurableObject, 'Include(RoleAssignments, RoleAssignments.Include(Member))');
Now in the getListPerms_onSucceeded() method you ought to be able to enumerate through listSecurableObject.get_roleAssignments() and get the members similar to how you're already doing it (although you'll probably want to use rAssignment.get_member().get_loginName() ).