Relay: Using first/after and last/before together (but not simultaneously)?

Created on 3 Oct 2016  路  5Comments  路  Source: facebook/relay

I can't understand if my use case is possible. Say a page loads and a connection is fetched with first = 10. Then when I scroll down I fetch another 10 by issuing relay.setVariables({ first: first + 10 }). And the newly fetched edges are appended to the connection.

Here's how it looks like:

------------   <= moment in time of page load

cursor 1
edge 1

cursor 2
edge 2

...

cursor n
edge n

Then say I've got a network disconnect and after reconnect I want to fetch everything that is above cursor 1 and it must be prepended to the connection. In my mind I have to issue relay.setVariables({ last: 10, before: 'cursor 1' }).

So that the page would look like:

cursor -k
edge -k

...

cursor -2
edge -2

cursor -1
edge -1

------------   <= moment in time of page load

cursor 1
edge 1

cursor 2
edge 2

...

cursor n
edge n

But I do not understand how to write a proper fragment for such a connection. It seems like I can only specify connection(first: $first) but not connection(first: $first, last: $last, before: $before).

Thanks.

All 5 comments

I've prepared the playground for this. Here's the link to the playground.

The idea is that I can load first + N but cannot load last + K before the first cursor.

I'll duplicate the code (without the schema) here (I'm taking it from the playground I've just mentioned).

class Route extends Relay.Route {
  static queries = {
    viewer: (Component) => Relay.QL`
        query {
          viewer {
            ${Component.getFragment('viewer')}
          }
        }
    `,
  };

  static routeName = 'Route';
}

class MsgsComponent extends React.Component {
  static propTypes = {
    viewer: React.PropTypes.object,
  };

  render() {
    console.log('render', this.props.viewer.msgs);
    return (
      <div>
        <button onClick={() => this.loadMoreBefore()}>Load more before</button>
        {this.props.viewer.msgs.edges.map(({ node, cursor }) => (
          <div>{node.id}&nbsp;{node.text}&nbsp;{cursor}</div>
        ))}
        <button onClick={() => this.loadMoreAfter()}>Load more after</button>
      </div>
    );
  }

  loadMoreBefore() {
    this.props.relay.setVariables({
      last: 1,
      before: '500',
      first: null,
    });
  }

  loadMoreAfter() {
    this.props.relay.setVariables({
      first: this.props.relay.variables.first + 1,
    });
  }
}

const MsgsContainer = Relay.createContainer(MsgsComponent, {
  initialVariables: {
    first: 10,
    after: null,
    last: null,
    before: null,
  },

  fragments: {
    viewer: () => Relay.QL`
        fragment on Viewer {
            msgs(first: $first, after: $after, last: $last, before: $before) {
                edges {
                    node {
                        id
                        text
                    }
                    cursor
                }
                pageInfo {
                    hasNextPage
                    hasPreviousPage
                }
            }
        }
    `,
  },
});

ReactDOM.render(<Relay.RootContainer Component={MsgsContainer} route={new Route()} />, mountNode);

I have same usecase.
But it looks like it's not possible to use both last and first on the same container?
see related https://github.com/facebook/relay/issues/1170 & https://github.com/facebook/relay/issues/540

can't we use to different connections as a workaround for now?

like:

firstMsgs: msgs(first: $first) {}
lastMsgs: msgs(last: $last) {}

and then concatenate them?

@sibelius I did not try it this way.. But the idea looks promising. I've solved my problem with graphql subscriptions that prepend a bunch of new edges after the network reconnect.

I'm sorry this issue has sat here for so long. In an attempt to clean up our issue queue we're closing some aging or unclear-action issues. Also, while this issue applies to Relay Classic, our team is trying to focus on Relay Modern going forward.

I believe this issue is much improved with Relay Modern.

If this issue is still important to you, please feel free to reopen it with an update.

Was this page helpful?
0 / 5 - 0 ratings