Losing state data after get request

I am having trouble maintaining my state data after a get request. i.e. the values I added in state.data are wiped and replaced with the result of the request.

Hey @etdvlpr , great question.

composeNextState is how state is handled between operations for almost all adaptors. Assuming that you’re making a get operation using the language-http adaptor, you’ll see that the data in the HTTP response gets added to state.data, and the previous value of state.data gets added to the state.references array. In this way, you can always access the response of previous requests. Check out how composeNextState works:

// from language-common
export function composeNextState(state, response) {
  return {
    ...state,
    data: response,
    references: [...state.references, state.data],
  };
}

composeNextState is used here by languate-http.

So if your job goes:

get("www.example.com/1");

get("www.example.com/2");

get("www.example.com/3");

fn(state => {
  console.log(
    'data from the response to "get #3"',
    state.data
   );
  
  console.log(
    'data from the responses to "get #2" and "get #1"',
    state.references
  );

  return state;
});

You’ll see that response data in state.data and an array of response data in state.references (something like [ ...respFrom2, ...respFrom1 ].

Hope this helps!

Yes it’s very helpful and, I am using the language-http adaptor. Is there a safe way to store variables processed from the first request to be used in consequent ones?

Absolutely. The only rule for that state object, which gets passed between operations in a single job and between jobs in a flow (using “success triggers” and “fail triggers”) is that it must be valid JSON.

In short, create your own special keys like this:

get(
  "www.example.com/patients",
  { query: { nid: "123" } },
  state => ({ ...state, patient: state.data })
);

get("www.example.com/clinics/7", { }, state => ({ ...state, clinic: state.data }));

fn(state => {
  console.log(state.patient) // here they are!
  console.log(state.clinic) // here it is!
  return state;
});

Note that in those operations, I’m using a callback as the third argument. The pattern for these language-http operations is req(path, params, callback) and you can see exactly how the callback is applied here.

Spoiler alert :slight_smile: it’s this…

function handleCallback(state, callback) {
  if (callback) return callback(state);
  return state;
}

So for all these callbacks you need to write a function that takes state and returns state.

Thanks for the great questions. Keep 'em coming! :mechanical_arm:

1 Like