title: React/NextJS: How can I map an array of objects whose keys change?
body: <p>I'm working on a project in NextJS and I found an interesting problem for which I can't seem to find a solution -</p>
  <p>I have an array of objects I've acquired from the Civic GAPI.  In this array, most the objects are general election contests, but some are also referendums.  The <code>contest</code> and <code>referendum</code> objects have different structures.</p>
  <p>Here's a general election <code>contest</code> object:</p>
  <pre><code>14:
  candidates: (2) [{…}, {…}]
  district: {name: &quot;Thurston County&quot;, scope: &quot;countywide&quot;, id: &quot;ocd-division/country:us/state:wa/county:thurston&quot;}
  level: [&quot;administrativeArea2&quot;]
  office: &quot;Commissioner District 3&quot;
  roles: [&quot;legislatorUpperBody&quot;]
  sources: [{…}]
  type: &quot;General&quot;
  __proto__: Object
  </code></pre>
  <p>And here's a <code>referendum</code> object:</p>
  <pre><code>15:
  district: {name: &quot;Washington&quot;, scope: &quot;statewide&quot;, id: &quot;ocd-division/country:us/state:wa&quot;}
  referendumTitle: &quot;Advisory Vote No. 8 (Senate Bill 6505)&quot;
  referendumUrl: &quot;https://wei.sos.wa.gov/agency/osos/en/press_and_research/PreviousElections/2014/General-Election/Pages/Online-Voters-Guide.aspx&quot;
  sources: [{…}]
  type: &quot;Referendum&quot;
  __proto__: Object
  </code></pre>
  <p>Here's my page that renders this data (I've included the entire page, but obviously you can skip the conditionals for loading the data from GAPI):</p>
  <pre><code>import useSWR from 'swr';
  
  const Contests = (props) =&gt; {
    const url = '/api/voterInfo';
    const fetcher = (url) =&gt; fetch(url).then((r) =&gt; r.json());
    const { data, error } = useSWR(url, fetcher);
  
    if (error)
      return (
        &lt;div className='alert alert-danger' role='alert'&gt;
          &lt;span className='sr-only'&gt;Failed to load data!&lt;/span&gt;
        &lt;/div&gt;
      );
  
    if (!data)
      return (
        &lt;div
          className='spinner-border spinner-border-lg text-danger'
          role='status'
          style={{ margin: '10rem', width: '20rem', height: '20rem' }}
        &gt;&lt;/div&gt;
      );
  
    if (data &amp;&amp; data !== null) {
      const { contests } = data.data;
  
      return (
        &lt;div&gt;
          &lt;table className='table table-hover'&gt;
            &lt;caption&gt;List of contests in your area&lt;/caption&gt;
            &lt;thead style={{ fontFamily: 'Righteous, sans-serif' }}&gt;
              &lt;tr&gt;
                &lt;th scope='col'&gt;#&lt;/th&gt;
                &lt;th scope='col'&gt;Dist ID&lt;/th&gt;
                &lt;th scope='col'&gt;Dist Name&lt;/th&gt;
                &lt;th scope='col'&gt;Dist Scope&lt;/th&gt;
                &lt;th scope='col'&gt;Office&lt;/th&gt;
                &lt;th scope='col'&gt;Type&lt;/th&gt;
              &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
              {contests.map((contest, idx) =&gt; (
                &lt;tr key={idx}&gt;
                  &lt;th scope={idx}&gt;{idx + 1}&lt;/th&gt;
  
                  &lt;td&gt;{contest.district.id}&lt;/td&gt;
                  &lt;td&gt;{contest.district.name}&lt;/td&gt;
                  &lt;td&gt;{contest.district.scope}&lt;/td&gt;
                  &lt;td&gt;{contest.office}&lt;/td&gt;
                  &lt;td&gt;{contest.type}&lt;/td&gt;
                &lt;/tr&gt;
              ))}
            &lt;/tbody&gt;
          &lt;/table&gt;
          {console.log(contests[0].level[0])}
        &lt;/div&gt;
      );
    }
  };
  
  export default Contests;
  </code></pre>
  <p>If I only render the first level of key-value pairs, it's easy to see how the difference in <code>contest</code> and <code>referendum</code> objects causes one or the other to miss values:</p>
  <p><a href="https://i.stack.imgur.com/IFqDm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IFqDm.png" alt="Missing values from referendumTitle, referendumUrl" /></a></p>
  <p>Because I've set the map to render the keys from <code>contests</code> it misses the <code>referendum</code> values for keys <code>referendumTitle</code> and <code>referendumUrl</code>.</p>
  <p>What's the best way to go about dealing with this?  I came up with two possible solutions I'm not sure how to implement:</p>
  <p>Is there a conditional I could set to only map contests, and have a separate page to map referendums?  How would I separate them (before/while/after) mapping an array?</p>
  <p>OR</p>
  <p>Is there a way to dynamically map the values of the keys regardless of their identifier?</p>
  <p>Any other ideas?</p>