I am trying to implement an interceptor in my Experience Builder 1.8 custom widget. Upgrading to latest Experience builder custom install is not an option right now. I need to intercept a url request and get json as the response and NOT pbf. This will fix an error I have with EXB1.8 and Enterprise 11.4.
I have read and tried to implement an interceptor, but not able to get it to actually work? Where in the Experience builder client code would I place this interceptor (file?) and/or what am I missing here. Currently I am just putting this in my Widget.tsx file of my custom witdget and it never gets fired.
Where do I put this in client directory? Currently I have at
client/your-extenstions/widgets/CustomNavbar/src/runtime/widget.tsx
import esriConfig from '@arcgis/core/config.js';
const myInterceptor = {
before: function (params) {
// Modify the request here
console.log('Intercepted request:', params);
return params;
},
after: function (response) {
// Modify the response here
console.log('Intercepted response:', response);
return response;
},
error: function (error) {
// Handle errors here
console.log('Intercepted error:', error);
return Promise.reject(error);
}
};
esriConfig.request.interceptors.splice(0, 0, myInterceptor);
Solved! Go to Solution.
Hi @MKa , please try the following code snippet
import { moduleLoader } from 'jimu-core'
const [esriConfig] = await loadModules(['esri/config']);
esriConfig.request.interceptors.splice(0, 0, myInterceptor);
Hi @MKa , please try the following code snippet
import { moduleLoader } from 'jimu-core'
const [esriConfig] = await loadModules(['esri/config']);
esriConfig.request.interceptors.splice(0, 0, myInterceptor);
That worked. I added the code as a widget and added to an experience to intercept the query.f == 'pbf' with query.f = 'json'. The only thing i don't understand is why I only had to do the intercept once, meaning it only hits the breakpoint on the first call. All subsequent calls to same url don't reach the "before" breakpoint. Anyways, this was the solution i was looking for. Here is the test widget for others with this problem. This was build with ExB 1.8.
import { moduleLoader } from 'jimu-core';
import React, { Component } from 'react';
class MyCustomWidget extends Component {
render() {
(async () => {
const [esriConfig] = await moduleLoader.loadModules(['esri/config']);
console.log("loading esri/config:" + esriConfig);
const myInterceptor = {
urls: [/\/server\/rest\/.*/],
before: function (params) {
//We intercept the pbf on the first call, All subsequent calls seem to follow the json rule, so after the first intercept this works
if (params.requestOptions.query.f == 'pbf' && params.requestOptions.query.resultType != 'tile') {
console.log('Intercepted request:', params);
console.log('esriConfig.request params.url = ' + params.url)
params.requestOptions.query.f = 'json';
}
else
{
console.log('SKIPPED esriConfig.request params.url = ' + params.url)
console.log('SKIPPED params.requestOptions.query.f = pbf = ' + params.requestOptions.query.f )
console.log('SKIPPED params.requestOptions.query.resultType = ' + params.requestOptions.query.resultType)
}
}
};
esriConfig.request.interceptors.splice(0, 0, myInterceptor);
})();
return (
<div>
<h1>Interceptor Widget</h1>
</div>
);
}
}
export default MyCustomWidget;
I suspect a reason this is only caught once is because it's inside the render method inside an IIFE (async () => {})
Even though render is part of React that Exb Builds upon, it can be called multiple times during a lifecycle, But the interceptor is only being attached once (think about it, if it was attaching every time, would it fire multiple times once?), and depending on that timing, the ArcGIS API may have already finish its important 'pbf' network call by the time your interceptor attaches.
Exb also by design heavily caches layers and webmap resources, So the interceptor is either:
1. not actually being setup early enough in the process.
2. There is nothing to intercept because future requests may actually be local and not going back to the server (so its maybe not being seen as a network request, and wouldn't fire)
Suggest moving the interceptor to ComponentDidMount
Perhaps like this:
import { moduleLoader } from 'jimu-core';
import React, { Component } from 'react';
class MyCustomWidget extends Component {
async componentDidMount() {
const [esriConfig] = await moduleLoader.loadModules(['esri/config']);
console.log("loading esri/config:", esriConfig);
const myInterceptor = {
urls: [/\/server\/rest\/.*/],
before: function (params) {
if (params.requestOptions.query.f === 'pbf' && params.requestOptions.query.resultType !== 'tile') {
console.log('Intercepted request:', params);
console.log('esriConfig.request params.url = ' + params.url)
params.requestOptions.query.f = 'json';
} else {
console.log('SKIPPED esriConfig.request params.url = ' + params.url)
console.log('SKIPPED params.requestOptions.query.f = pbf = ' + params.requestOptions.query.f)
console.log('SKIPPED params.requestOptions.query.resultType = ' + params.requestOptions.query.resultType)
}
}
};
esriConfig.request.interceptors.splice(0, 0, myInterceptor);
}
render() {
return (
<div>
<h1>Interceptor Widget</h1>
</div>
);
}
}
export default MyCustomWidget;
Otherwise, the only other idea I can think of is that this might belong, not at a Widget Level, but App Level, I'm not sure off hand the best way to even attempt that though 😕