Polaris-react: [ResourceList] Selecting all versus selecting my checkbox call back with different IDs

Created on 3 Nov 2018  路  4Comments  路  Source: Shopify/polaris-react

Issue summary

When using the "select all" part of the bulk action, the selection IDs are based on the IDs of the raw data. When using the individual checkboxes, the selection IDs are based on the ID of the resource list item.

Expected behavior

It is always based on the IDs of the data.

Reduced test case

const customers = [
  {id: 'gid://Shopify/Customer/1', displayName: 'Tim'},
  {id: 'gid://Shopify/Customer/2', displayName: 'Dan'},
]

class MyComponent extends React.Component {
  state = {selectedCustomers: []};

  render() {
    return (
      <ResourceList
        items={customers}
        selectedItems={this.state.selectedCustomers}
        bulkActions={[{content: 'Delete', onAction: () => {}}]}
        onSelectionChange={(selectedCustomers) => this.setState({selectedCustomers})}
        renderItem={(customer) => (
          <ResourceList.Item
            id={/* parseGid just gets the number portion */ `Customer${parseGid(customer.id)}`}
          >
            {customer.displayName}
          </ResourceList.Item>
        )}
      />
    );
  }
}

Specifications

  • Are you using the React components? (Y/N): Y
  • Polaris version number: latest 2.x
  • Browser:
  • Device:
  • Operating System:
Good first issue Icebox 馃悰Bug

Most helpful comment

I experienced similar issue and noticed that there is a prop in ResourceList called "idForItem".
If you specify this prop to select id of each item, selecting individually and selecting all will behave the same.
For example:

<ResourceList items={customers} idForItem={(customer)=>(customer.id)}

and when you render item,

renderItem={(customer, id) => (<ResourceList.Item id={id}> {customer.displayName} </ResourceList.Item>)}

All 4 comments

Here's a reproducible version to be copied in Playground.tsx:

import * as React from 'react';
import {Page, ResourceList} from '@shopify/polaris';

interface State {}

const customers = [
  {id: 'gid://Shopify/Customer/1', displayName: 'Tim'},
  {id: 'gid://Shopify/Customer/2', displayName: 'Dan'},
];

export default class Playground extends React.Component<never, State> {
  state = {selectedCustomers: []};

  getLastIndex(idString) {
    return idString.split('/').pop();
  }

  render() {
    return (
      <Page title="Playground">
        {/* Add the code you want to test here */}
        <ResourceList
          items={customers}
          selectedItems={this.state.selectedCustomers}
          bulkActions={[{content: 'Delete', onAction: () => {}}]}
          onSelectionChange={(selectedCustomers) =>
            this.setState({selectedCustomers})
          }
          renderItem={(customer) => {
            return (
              <ResourceList.Item id={this.getLastIndex(customer.id)}>
                {customer.displayName}
              </ResourceList.Item>
            );
          }}
        />
      </Page>
    );
  }
}

@lemonmade The scenario happens because the ids of customers provided to the item prop of ResourceList doesn't correspond to the ids of customers provided to the id prop of ResourceList.Item.

If they are the same, then this wouldn't happen e.g:
<ResourceList.Item id={customer.id}> ...

This is something that the developer can prevent so I'm wondering if it is still considered a bug in the component, would need your input on this 馃槃

I have encountered the same issue! Here is another example that can reproduce the issue.
https://codesandbox.io/s/qk4r323mw6

I basically change the id to eid to the payload of each item. The bulk action will behave incorrectly when you perform select all action.

I experienced similar issue and noticed that there is a prop in ResourceList called "idForItem".
If you specify this prop to select id of each item, selecting individually and selecting all will behave the same.
For example:

<ResourceList items={customers} idForItem={(customer)=>(customer.id)}

and when you render item,

renderItem={(customer, id) => (<ResourceList.Item id={id}> {customer.displayName} </ResourceList.Item>)}

This issue has been inactive for 180 days and labeled with Icebox. It will be closed in 7 days if there is no further activity.

Was this page helpful?
0 / 5 - 0 ratings