0

So here's the javascript I use to display item name of selected item from an external list:

    <script type="text/javascript">
      var targetListItem;
      function ShowSelectedItems() {
      var ctx = SP.ClientContext.get_current();
      var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
      var key;
      for (key in selectedItems) {
         var clientContext = new SP.ClientContext(); 
         var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
         targetListItem = targetList.getItemById(selectedItems[key].id);
         clientContext.load(targetListItem, 'Item');
         clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
       }
    }
       function onQuerySucceeded() {

           alert('Request succeeded. \n\nRetrieved Item is: ' + targetListItem.get_item('Item'));

       }

       function onQueryFailed(sender, args) {
         alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
       } 
    </script>
    <a href="#" onclick="javascript:ShowSelectedItems();">Show Items</a>

It works fine if I only select one item, but if I select multiple items it will only display the first item and print this error in console:

SCRIPT5022: The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. sp.js, line 2 character 158961

Can someone please help me to troubleshoot this problem?

UPDATE: Here's updated version of the code, unfortunately I'm still getting same error:

<script type="text/javascript">
function ShowSelectedItems() {
    var ctx = SP.ClientContext.get_current();
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
    var key, targetListItems = [],index =0;
    for (key in selectedItems) {
       var clientContext = new SP.ClientContext(); 
       var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
       var targetListItem = targetList.getItemById(selectedItems[key].id);
       targetListItems[index] = targetListItem;
       clientContext.load(targetListItems[index], 'Item');//load listitem
       index++;
     }
    clientContext.executeQueryAsync(function(){
      var i;
      for(i in targetListItems){
         alert('Request succeeded. \n\nRetrieved Item is: ' + targetListItems[i].get_item('Item'));
      }
    }, function(s,a){alert(a.get_messgae());});
}
    </script>
    <a href="#" onclick="javascript:ShowSelectedItems();">Show Items</a>

1 Answer 1

2

You cannot use executeQueryAsync in a loop, the loop execution does not wait for the execute Query call completion(it is async). So try to load all items once and call 'executeQueryAsync' outside of the loop and also we should not create the clientContext and list objects inside the loop(if so, only the last object inside the loop will have correct context association). Move those statements to top of for loop

    var ctx = SP.ClientContext.get_current();
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
    var key, targetListItems = [],index =0;
    var clientContext = new SP.ClientContext(); 
    var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
    for (key in selectedItems) {
       var targetListItem = targetList.getItemById(selectedItems[key].id);
       targetListItems[index] = targetListItem;
       clientContext.load(targetListItems[index], 'Item');//load listitem
       index++;
    }
    clientContext.executeQueryAsync(function(){
      //access the 'targetListItems' here. it is an array of SP.ListItem objects,loop through it
    }, function(s,a){alert(a.get_messgae());});

Another workaround

if you are Showing the 'Item' column value on the listview webpart, There is no need to load items from server. Use the following snippet to get the values of 'Item' column

var data = ctx.ListData.Row;// could be ctx2 or ctx3 in your case
var selectedids = SP.ListOperation.Selection.getSelectedItems();

var IdMap = {};

$.map(data,function(item,index){IdMap[item.ID] = item.Item})
var selectedvalues = $.map(selectedids,function(item,index){return IdMap[item.id]})

The 'selectedvalues' returns an array of the 'Item' column values

2
  • Hi, thanks for help! I updated my code based on your suggestion(see update section in question), unfortunately I'm still getting the same error. Did I do something wrong?
    – SSilicon
    Commented Aug 21, 2015 at 16:02
  • Figured it out. we were creating clientContext in side loop, so only the last item will be having the correct context, that should not be the case. We need to create context and list objects outside of loop. Modified my code to make it work, working in my environment. Commented Aug 21, 2015 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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