locked
Could not retrieve Option Set value from parent object using JavaScript RRS feed

  • Question

  • AccountCategoryCode- option set attribute. Trying:

       SDK.JQuery.retrieveMultipleRecords(
         "Account",
         "$select=Fax,AccountCategoryCode&$filter=AccountId eq guid'"+ GUID +"'", ....

           alert(results[0].AccountCategoryCode.name);

    result:

    or [object Object].


    Если сообщение оказалось полезным, пожалуйста, проголосуйте за него или пометьте в качестве ответа.


    • Edited by Dismantled Thursday, May 22, 2014 2:31 PM
    Thursday, May 22, 2014 2:29 PM

Answers

  • the function GetOptionSetLabel is asynchronous but you are calling it like a synchronous function, in addition the second parameter is not the value but the field name (accountcategorycode)

    I created a synchronous function for you, you need to insert it inside your SDK.Metadata.js web resource:

    (find this line this.RetrieveEntity = function (EntityFilters, LogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack, passThroughObject) { and put my code before)

     this.SyncGetOptionSetLabels = function(entityName, attributeName) {
      var request = [
      "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">",
      "<soapenv:Header><a:SdkClientVersion xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">6.0</a:SdkClientVersion></soapenv:Header>",
       "<soapenv:Body>",
        "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">",
         "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">",
          "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>EntityLogicalName</b:key>",
            "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entityName.toLowerCase() + "</b:value>",
           "</a:KeyValuePairOfstringanyType>",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>MetadataId</b:key>",
            "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">00000000-0000-0000-0000-000000000000</b:value>",
           "</a:KeyValuePairOfstringanyType>",
            "<a:KeyValuePairOfstringanyType>",
            "<b:key>RetrieveAsIfPublished</b:key>",
          "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">true</b:value>",
           "</a:KeyValuePairOfstringanyType>",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>LogicalName</b:key>",
            "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeName.toLowerCase() + "</b:value>",
           "</a:KeyValuePairOfstringanyType>",
          "</a:Parameters>",
          "<a:RequestId i:nil=\"true\" />",
          "<a:RequestName>RetrieveAttribute</a:RequestName>",
         "</request>",
        "</Execute>",
       "</soapenv:Body>",
      "</soapenv:Envelope>"].join("");
    
      var req = new XMLHttpRequest();
      req.open("POST", _getUrl() + "/XRMServices/2011/Organization.svc/web", false);
      try { req.responseType = 'msxml-document'} catch(e){}
      req.setRequestHeader("Accept", "application/xml, text/xml, */*");      
      req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
      req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
      req.send(request);
      var doc = req.responseXML;
      try{_setSelectionNamespaces(doc);}catch(e){}
      return _objectifyNode(_selectSingleNode(doc, "//b:value"));
    }

    after you can call in this way:

    var result = SDK.Metadata.SyncGetOptionSetLabels("Account", "AccountCategoryCode");
    
    var optionsetValue = 1; // value to check
      for (var i = 0; i < result.OptionSet.Options.length; i++) {
        var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
        var value = result.OptionSet.Options[i].Value;
        if (value == optionsetValue) {
           alert("the label is " + text);
        }
      }


    My blog: www.crmanswers.net - Rockstar 365 Profile


    Thursday, May 22, 2014 7:15 PM

All replies

  • 1-Check the error on the service.response of the oData Call.

    2- Verify if you acctually bring something on the Query

     
    Thursday, May 22, 2014 2:39 PM
  • to get the integer value of the optionset try with:

    var categorycode = eval(results[0].AccountCategoryCode.Value);



    My blog: www.crmanswers.net - Rockstar 365 Profile

    Thursday, May 22, 2014 2:48 PM
  • var categorycode = eval(results[0].AccountCategoryCode.Value);
    alert(results[0].Fax);
    alert(results[0].categorycode);

    Fax returns correct value

    categorycode - null or undefined


    Если сообщение оказалось полезны&#1084;, пожалуйста, проголосуйте за него или по&#1084;етьте в качестве ответа.

    Thursday, May 22, 2014 2:57 PM
  • sorry again

    Now "categorycode" returns the digid.

    But there is a symbol value in it (A, B, C etc).



    • Edited by Dismantled Thursday, May 22, 2014 3:12 PM
    Thursday, May 22, 2014 3:12 PM
  • the REST endpoint returns only the integer value of the optionset, if you need the label, you need to retrieve it querying the metadata, an example here:

    http://guruprasadcrm.blogspot.pt/2011/07/retrieving-optionset-lable-data-using.html

    check also the latest comment on that page


    My blog: www.crmanswers.net - Rockstar 365 Profile


    Thursday, May 22, 2014 3:18 PM
  • Guido, thanks for the link.

    I've done:

    1. Add web resource SDK.Metadata.js (from here http://msdn.microsoft.com/en-us/library/gg594428.aspx)

    2. Add web resource function

    function GetOptionSetLabel(EntityLogicalName, AttributeLogicalName) {
    	SDK.Metadata.RetrieveAttribute(EntityLogicalName, AttributeLogicalName, "00000000-0000-0000-0000-000000000000", true,
        function (result) {
    		for (var i = 0; i < result.OptionSet.Options.length; i++) {
    			var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
    			var value = result.OptionSet.Options[i].Value;
    		}
    	},
    	function (error) { }
    	);
    }

    3. Add code to main script:

           var categorycode = eval(results[0].AccountCategoryCode.Value);
          alert(categorycode); // returns result is "3"
           var categoryAttr = GetOptionSetLabel("Account", categorycode);
           alert(categoryAttr); // does not return anything

    where did I go wrong?


    Если сообщение оказалось полезны&#1084;, пожалуйста, проголосуйте за него или по&#1084;етьте в качестве ответа.

    Thursday, May 22, 2014 4:35 PM
  • the function GetOptionSetLabel is asynchronous but you are calling it like a synchronous function, in addition the second parameter is not the value but the field name (accountcategorycode)

    I created a synchronous function for you, you need to insert it inside your SDK.Metadata.js web resource:

    (find this line this.RetrieveEntity = function (EntityFilters, LogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack, passThroughObject) { and put my code before)

     this.SyncGetOptionSetLabels = function(entityName, attributeName) {
      var request = [
      "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">",
      "<soapenv:Header><a:SdkClientVersion xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">6.0</a:SdkClientVersion></soapenv:Header>",
       "<soapenv:Body>",
        "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">",
         "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">",
          "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>EntityLogicalName</b:key>",
            "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entityName.toLowerCase() + "</b:value>",
           "</a:KeyValuePairOfstringanyType>",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>MetadataId</b:key>",
            "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">00000000-0000-0000-0000-000000000000</b:value>",
           "</a:KeyValuePairOfstringanyType>",
            "<a:KeyValuePairOfstringanyType>",
            "<b:key>RetrieveAsIfPublished</b:key>",
          "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">true</b:value>",
           "</a:KeyValuePairOfstringanyType>",
           "<a:KeyValuePairOfstringanyType>",
            "<b:key>LogicalName</b:key>",
            "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeName.toLowerCase() + "</b:value>",
           "</a:KeyValuePairOfstringanyType>",
          "</a:Parameters>",
          "<a:RequestId i:nil=\"true\" />",
          "<a:RequestName>RetrieveAttribute</a:RequestName>",
         "</request>",
        "</Execute>",
       "</soapenv:Body>",
      "</soapenv:Envelope>"].join("");
    
      var req = new XMLHttpRequest();
      req.open("POST", _getUrl() + "/XRMServices/2011/Organization.svc/web", false);
      try { req.responseType = 'msxml-document'} catch(e){}
      req.setRequestHeader("Accept", "application/xml, text/xml, */*");      
      req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
      req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
      req.send(request);
      var doc = req.responseXML;
      try{_setSelectionNamespaces(doc);}catch(e){}
      return _objectifyNode(_selectSingleNode(doc, "//b:value"));
    }

    after you can call in this way:

    var result = SDK.Metadata.SyncGetOptionSetLabels("Account", "AccountCategoryCode");
    
    var optionsetValue = 1; // value to check
      for (var i = 0; i < result.OptionSet.Options.length; i++) {
        var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
        var value = result.OptionSet.Options[i].Value;
        if (value == optionsetValue) {
           alert("the label is " + text);
        }
      }


    My blog: www.crmanswers.net - Rockstar 365 Profile


    Thursday, May 22, 2014 7:15 PM
  • Your solution works perfectly!!!

    Great work! Thanks a lot!
    • Edited by Dismantled Thursday, May 22, 2014 7:50 PM
    Thursday, May 22, 2014 7:45 PM