Skip to content
On this page

Operation copying

DANGER

This topic is considered obsolete since v0.12 and will be removed in v0.14. Please read this ADR for more information and migration guide.

It is advanced topic, so you can write an application without it. But it is useful when you have a lot of similar Queries and Mutations and want to simplify your code.

You will learn:

  • When you need to copy Queries and Mutations
  • How to copy Queries and Mutations
  • How to simplify your code with Queries and Mutations copying

Use-case for copying Queries and Mutations

Let's revise the example from the previous chapters. We have two Queries: characterQuery and originQuery. Let's imagine, we want to add a new Query currentLocationQuery that will be similar to originQuery, but will fetch the current location of the character.

ts
const characterQuery = createQuery(/* ... */);

const originQuery = createQuery({
  handler: async ({ originUrl }) => {
    const response = await fetch(originUrl);
    return response.json();
  },
});

const currentLocationQuery = createQuery({
  handler: async ({ currentLocationUrl }) => {
    const response = await fetch(currentLocationUrl);
    return response.json();
  },
});

As you can see, the only difference between originQuery and currentLocationQuery is parameters, so it would be nice to have a way to copy the Query and change only the parameters.

Extract base Query

To copy the Query, we need to extract the base Query that will be used as a template for the new ones:

ts
const locationQuery = createQuery({
  handler: async ({ locationUrl }) => {
    const response = await fetch(locationUrl);
    return response.json();
  },
});

Now, we can copy the locationQuery and change only the parameters:

ts
import { attachOperation } from '@farfetched/core'

const originQuery = attachOperation(locationQuery, {
  mapParams: ({ originUrl }) => ({
    locationUrl: originUrl
  }),
});

const currentLocationQuery = attachOperation(locationQuery, {
  mapParams: ({ currentLocationUrl }) => ({
    locationUrl: currentLocationUrl
  }),
});

So, originQuery and currentLocationQuery are copies of locationQuery, they have separate states and can be used independently.

Additional parameters from external source

If you want to use additional parameters from external source, you can use the source field of attachOperation config:

ts
import { createStore } from 'effector';
import { attachOperation } from '@farfetched/core';

const $someExtarnalSource = createStore({});

const currentLocationQuery = attachOperation(locationQuery, {
  source: $someExternalSource,
  mapParams: ({ currentLocationUrl }, valueOfExternalSource) => ({
    locationUrl: currentLocationUrl,
  }),
});

In this case, the valueOfExternalSource will be equal to the current value of the $someExternalSource Store.

Using attachOperation with Mutations

The attachOperation operator can be used with Mutations as well:

ts
import { attachOperation } from '@farfetched/core';

const baseMutation = createMutation(/* ... */);
const newMutation = attachOperation(baseMutation);

API reference

You can find the full API reference for the attachOperation operator in the API reference.

Released under the MIT License.