Skip to content

Instantly share code, notes, and snippets.

@CheeseCake87
Created September 26, 2023 12:59
Show Gist options
  • Save CheeseCake87/de0ca65927169fb730d91c8b51a38c4f to your computer and use it in GitHub Desktop.
Save CheeseCake87/de0ca65927169fb730d91c8b51a38c4f to your computer and use it in GitHub Desktop.
// imports here
const server_url = '127.0.0.1:5000';
export default function Client() {
const url_params = useParams();
// places dely on the amount of times a function is called, used in the form input onInput tag.
function debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
}
// builds the url used to fetch GET the client
function apiGetClientURL(client_id) {
return `http://${server_url}/clients/client/${client_id}`;
}
// builds the url used to fetch POST the client
function apiSetClientURL(client_id) {
return `http://${server_url}/clients/client/${client_id}/update`;
}
// fetch the client from the API
async function apiGetClient(client_id, {value, refetching}) {
const client = await fetch(apiGetClientURL(client_id));
if (client.ok) {
const jsond = await client.json();
if (jsond['Client']) {
if (jsond['Client'][0]) {
return jsond['Client'][0];
} else {
throw new Error('Client has no data');
}
} else {
throw new Error('Client data not found');
}
} else {
throw new Error('Client not found');
}
}
// POST the modified data to the API
async function apiSetClient(client_id, updated_values) {
const client = await fetch(
apiSetClientURL(client_id),
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(updated_values)
}
);
return client.ok;
}
// A class to make working with SolidJS createResource a little nicer with HTML forms.
class ResourceForm {
__signal_registry__ = {};
// stores the results from creating a SolidJS createResource, and takes in the function
// responsible for sending the POST request (JSON) to the API.
// Also creates SolidJS signals on the fly.
constructor(
{
fetcher = null,
mutater = null,
refetcher = null,
apiSetFunc = null,
apiSetArgs = null,
} = {}
) {
if (!fetcher) throw new Error('ResourceForm: fetcher is required');
if (!mutater) throw new Error('ResourceForm: mutater is required');
if (!refetcher) throw new Error('ResourceForm: refetcher is required');
this.f = fetcher;
this.m = mutater;
this.r = refetcher;
this.apiSetFunc = apiSetFunc;
this.apiSetArgs = apiSetArgs;
}
createSignal(key) {
const [value, setValue] = createSignal(this.f()[key]);
this.__signal_registry__[key] = {getter: value, setter: setValue};
}
getValue(key) {
return this.f.loading ? null : this.f()[key];
}
setValue(key, value) {
if (!this.__signal_registry__.hasOwnProperty(key)) {
this.createSignal(key);
}
this.m((ogv) => {
ogv[key] = value;
if (this.apiSetFunc) {
this.apiSetFunc(Object.values(this.apiSetArgs), ogv);
}
this.__signal_registry__[key].setter(value);
return ogv
});
}
watchValue(key) {
if (!this.__signal_registry__.hasOwnProperty(key)) {
this.createSignal(key);
}
return this.__signal_registry__[key].getter;
}
refreshResource() {
this.r();
}
}
// SolidJS createResource
const [
client_fetch,
{
mutate: client_mutate,
refetch: client_re_fetch
}
] = createResource(url_params.client_id, apiGetClient);
// Instance of the ResourceForm
const client_form = new ResourceForm(
{
fetcher: client_fetch,
mutater: client_mutate,
refetcher: client_re_fetch,
apiSetFunc: apiSetClient,
apiSetArgs: {
client_id: url_params.client_id
}
});
// return the code to the browser
return (
<div class={styles.App}>
<form>
<div class={styles.test_box}>
<label for="first_name">First Name</label>
<input
type="text" id="first_name" name="first_name"
value={client_form.getValue('first_name')}
onInput={debounce((e) => client_form.setValue('first_name', e.target.value), 1000)}
/>
<label for="last_name">Last Name</label>
<input
type="text" id="last_name" name="last_name"
value={client_form.getValue('last_name')}
onInput={debounce((e) => client_form.setValue('last_name', e.target.value), 1000)}
/>
<button type="button" onClick={() => client_form.refreshResource()}>Refresh</button>
<Show when={!client_fetch.loading}>
<p>{client_form.watchValue('first_name')}</p>
<p>{client_form.watchValue('last_name')}</p>
</Show>
</div>
</form>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment