Created
September 26, 2023 12:59
-
-
Save CheeseCake87/de0ca65927169fb730d91c8b51a38c4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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