I have some web components created using lit elements. And Those includes some api requests to send and fetch data from another site and I am hoping to send some data through api request header. So I am hoping to create one common function to contain those header details incase if i need to change them in the future, i won't need to edit those component one by one. I need a solution like below :
common_function.js
function api_request(url) {
// content
}
my_component.js
import '/common_function.js';
...
constructor(){
api_request('http://apiRequestUrl');
}
Please let me know a way to achieve this using lit element. Thanks in advance.
Ok.. I found a solution. But I don't know whether this is the perfect answer for this. We can use lit Reactive Controllers to do the job. Here is the example How i did it.
common_function.js
import {initialState, Task} from '@lit-labs/task';
import * as SETTINGS from "../../bmw_settings";
export class ApiRequestController {
host;
url;
id;
task;
data = '';
_bmw_send_api_request() {
this.task = new Task(
this.host,
async ([data]) => {
const response = await fetch(
`${SETTINGS.BASE_URL + this.url}`,
{
headers: {
"Content-Type": "application/json",
'Access-Control-Request-Headers': 'Api-key, Content-Type',
'Api-key': '123'
}
}
);
const result = await response.json();
const error = result.error;
if (error !== undefined) {
throw new Error(error);
}
return result;
},
() => [this.data]
);
}
constructor(host, url, id) {
this.host = host;
this.url = url;
this.id = id;
this._bmw_send_api_request();
}
set data(value) {
this.data = value;
this.host.requestUpdate();
}
get data() {
return this.data;
}
render(renderFunctions) {
return this.task.render(renderFunctions);
}
}
my_component.js
import { LitElement, html} from 'lit';
import {ApiRequestController} from '../../common_functions';
class search_bar extends LitElement {
static properties = {
provider_type : String,
reasons : Array,
}
constructor() {
super();
this._getAllReasons();
}
async _getAllReasons(){
this.reasons = await new ApiRequestController(this, '/api/v1/get-reasons', 'search_bar');
}
render() {
return html `
${this.reasons.render({
complete: (data) => html `
<p>Reasons List</p>
<select>
<option>Select Reason</option>
${data.data.map((val) =>
html `<option value="${val.id}">${val.reason}</option>`
)}
</select>
`,
})}
`;
}
}
customElements.define('search-bar', search_bar)
use this documentation if you need more details. Thank you
How to create a common function which you can import and reuse has nothing to do with lit.
So when you have a common function in a file named 'common.js':
export default txt => {
console.log('Hello from a common function!', txt);
}
You can use it in another javascript file, including lit components, like this:
import commonfunction from '/path/to/your/common.js';
commonfunction('Wow!');
What may be a problem (but which is not your question) is that your browser does not import lit with the lit import you may have specified... because it may be a npm package on your server. Even when you serve the node_modules folder and you specify the exact path and filename, your lit import may include other other imports that brake because of how they are specified as resolved by node.
Therefore you may have to use something like RollupJS which can distribute your app resources with proper imports. See https://rollupjs.org/guide/en/
Hope this helps.