Skip to main content
Version: v3

Method Metadata

Method instances exist throughout alova's whole request lifecycle, and a project typically has many of them. Sometimes you need to attach extra information to a specific method instance to identify it or pass data along — that is what method metadata is for.

Use metadata to identify identities

Use identity before request

For example, most of the interfaces in your project need to be accompanied by token for each request, but there are still some interfaces that do not require verification. You may handle them uniformly in the global beforeRequest function.

const nonvalidateRequiredApi = [
'/api/url1',
'/api/url2',
'/api/url3'
// ...
];

createAlova({
beforeRequest(method) {
if (!nonvalidateRequiredApi.includes(method.url)) {
method.config.headers.token = '...';
}
}
});

This will cause the following two problems:

  1. Information is not aggregated with method instances, making maintainability even worse;
  2. Coding is more troublesome;

To solve these two problems, we will use metadata to identify a specific method instance when it is created.

Step 1: Define metadata when creating method instance

const loginAPI = (username, password) => {
const methodInstance = alovaInst.Post('/login', {
username,
password
});
methodInstance.meta = {
ignoreToken: true
};
return methodInstance;
};

And you can also directly define metadata in config

const loginAPI = (username, password) => {
return alovaInst.Post(
'/login',
{
username,
password
},
{
meta: {
ignoreToken: true
}
}
);
};

Step 2: Use metadata as the basis for judgment in beforeRequest

createAlova({
// ...
beforeRequest(method) {
if (!method.meta?.ignoreToken) {
method.config.headers.token = '...';
}
}
});

Use the identity after the response

This method can also be used in global responded. For example, in most cases, the request api will return json data, but there may be a file download interface, which will return a binary data stream. In this case Below, you can use different metadata in responded to handle different responses separately.

Step one: When creating a method instance, you also need to assign a metadata

const downloadAPI = filePath => {
const methodInstance = alovaInst.Post('/download_file', {
filePath
});
methodInstance.meta = {
isDownload: true
};
return methodInstance;
};

Step 2: Use metadata in responded as a basis for judgment

createAlova({
// ...
responded: {
onSuccess: (response, method) => method.meta?.isDownload ? response.blob() : response.json()
onError: (error, method) => {
//Metadata of method instances can also be accessed when responding to errors
}
}
});

Use metadata to pass information

In some cases, if you want to add additional information to different method instances for use elsewhere, you can also use metadata to save it. Take uniformly generating different method instance IDs as an example.

createAlova({
beforeRequest(method) {
if (!method.meta.generateId) {
method.meta.uid = generateUUID();
}
},

responded: {
onSuccess(response, method) {
// Access the meta data generated by the current method when the request is successful.
const currentMethodUID = method.meta.uid;
},
onError(error, method) {
//Access the meta data generated by the current method when the request fails.
const currentMethodUID = method.meta.uid;
}
}
});

Tips for non-typescript projects

In a non-typescript environment, you can use any attribute as an information carrier, not limited to the meta attribute.

methodInstance.showResponseMsg = true;
methodInstance.others = 'abc';

Only in a TypeScript environment will an arbitrary property name raise the error Property '$0' does not exist (ts(2339)), so in the type we designate meta as the information carrier.