How to create a json string in protractor from values in a dropdown
<p>Say you've got a dropdown that you wish to verify.  A decent method (correct me if I'm wrong) is to compare the values against a JSON array (stringified) of expected values.</p>

<pre><code>&lt;select&gt;
  &lt;option value="--"&gt;Pick a State&lt;/option&gt;
  &lt;option value="AL"&gt;Alabama&lt;/option&gt;
  &lt;option value="AK"&gt;Alaska&lt;/option&gt;
  ...
&lt;/select&gt;
</code></pre>

<p>I have finally figured out how to get the "value" attribute and the text value, particularly from an array. (Not an easy feat for the beginning javascript guy.)</p>

<p>Anyway, I have worked it out to:</p>

<pre><code>var actual = [];
$$('select option').each( function(el) {
  var name = '';
  var abbrev = '';

  el.getText().then(function(s) { 
    name = s; 
  }); 

  el.getAttribute('value').then(function (val) { 
    console.log("val = {"+val+"}"); 
    abbrev = val; 
  });

  console.log("abbrev = {"+abbrev+"}");  
  arr.push({ "name": name, "abbreviation": abbrev 
}); 
</code></pre>

<p>The result comes out as you may expect... well those who are very familiar.</p>

<pre><code>abbrev = {}
abbrev = {}
abbrev = {}
val = {--}
val = {AL}
val = {AK}
</code></pre>

<p>And <code>actual</code> looks like:</p>

<pre><code>[ 
  { name: '', abbreviation: '' },
  { name: '', abbreviation: '' },
  { name: '', abbreviation: '' } 
]
</code></pre>

<p>As can be seen, the <code>.then</code> method happens after its containing block has completed execution.</p>

<p>My question is, how do I go about fixing it so that I can get a result of:</p>

<pre><code>[
  { "name": "Pick your State", "abbreviation": "--" },
  { "name": "Alabama", "abbreviation": "AL" },
  { "name": "Alaska", "abbreviation": "AK" }
]
</code></pre>

<p>NOTE:
For others who may happen upon this question in the future:
<code>$$('')</code> is shorthand and equivalent to (as far as I know) <code>element.all(by.css(''))</code>.  And <code>$('')</code> is shorthand for <code>element(by.css(''))</code></p>

<p><strong>UPDATE:</strong></p>

<p>I've got it almost figured out.</p>

<pre><code>var actual = []; 
ddOption.each(function(el) { 
  actual.push({ 
    "name": el.getText().then(function(s) { return s; }), 
    "abbreviation": el.getAttribute('value').then(function(s) { return s; }) 
  }); 
});
</code></pre>

<p>So, when I do a call, such as <code>actual[2].name</code> I get <code>Alaska</code> in return and <code>actual[2].abbreviation</code> gives me <code>AK</code>.
However, if I try to put that into a string</p>

<pre><code>actual[2].abbreviation + ' = ' + actual[2].name
</code></pre>

<p>I get the Promise information as a string. Same when I try actual[2].name.valueOf().</p>

<pre><code>ManagedPromise::1372 {[[PromiseStatus]]: "fulfilled"} = ManagedPromise::1363 {[[PromiseStatus]]: "fulfilled"}
</code></pre>

<p>How do I convert the returned value of a promise as a string?</p>

<p><strong>LIVE EXAMPLE:</strong></p>

<p>One can produce a live example of what I'm trying to do.</p>

<ol>
<li>Start protractor in elementExplorer: <code>protractor --elementExplorer</code></li>
<li>Disabled synchronization (the page we're going to has the angular app in an iFrame): <code>browser.ignoreSynchronization = true;</code></li>
<li>Get the page: <code>browser.driver.get('http://www.w3schools.com/angular/tryit.asp?filename=try_ng_select')</code></li>
<li>Switch to the iframe: <code>browser.switchTo().frame('iframeResult')</code></li>
<li>Set ddOption: <code>var ddOption = $$('select option')</code></li>
<li>All in one line (because elementExplorer doesn't handle multiline commands... at least not in a way that I can tell), we're going to reset <code>actual</code> and then do the magic (the breakdown of the single line is shown above in the update):
<code>var actual = []; ddOption.each( function(el) { actual.push({ "name": el.getText().then(function(s) { return s; }), "abbreviation": el.getAttribute('value').then(function(s) { return s; }) }); });</code>

<ol start="7">
<li>Type <code>actual[1].name</code> and get <code>Emil</code> as an output</li>
<li>Type <code>actual[1].name + ' = ' + actual[1].abbreviation</code> and get the following as an output. <code>ManagedPromise::929 {[[PromiseStatus]]: "fulfilled"} = ManagedPromise::938 {[[PromiseStatus]]: "fulfilled"}</code> where I was hoping to get <code>Emil = string:Emil</code></li>
</ol></li>
</ol>