Update data records in an Oracle JET virtual DOM app
Introduction
This tutorial shows you how to use your Oracle JavaScript Extension Toolkit (Oracle JET) virtual DOM app to update an existing data record and submit it to a REST service.
Objectives
In this tutorial, you will learn how to update an existing data record and submit it to a REST service.
Prerequisites
- A development environment set up to create Oracle JET virtual DOM apps that includes an installation of Node.js
- Completion of the previous tutorial in this learning path, Create a Form to Create Data Records in an Oracle JET Virtual DOM App
Task 1: Create Components to Manage Form Information
Create a new component that will display a dialog to invoke the functionality to update a record.
-
Navigate to the
JET-Virtual-DOM-app/src/components/ActivityItemdirectory, create a newEditItemDialog.tsxfile, and open it in an editor. -
Add the placeholder entries that define a function name (
EditItemDialog) for the new component.import { h } from "preact"; type Props = { message?: string; }; const EditItemDialog = (props: Props) => { return ( <div class="oj-web-applayout-max-width oj-web-applayout-content"> <p>content</p> </div> ); }; export default EditItemDialog;
Task 2: Handle Opening the Dialog
Declare the type and function in the ItemActionsContainer component to invoke the EditItemDialog component that contains the functionality to update a record.
-
Navigate to the
JET-Virtual-DOM-app/src/components/ActivityItemdirectory and open theItemActionsContainer.tsxfile. -
At the top of the file, import the
useStateanduseEffectPreact hooks, define the additional properties in aPropstype alias that you require to use theEditItemDialogcomponent, and then define anItemtype alias.import { h } from "preact"; import "ojs/ojbutton"; import { useState, useEffect } from "preact/hooks"; type Props = { create: () => void; edit: () => void; itemSelected: Partial<Item>; }; type Item = { id: number; name: string; short_desc?: string; price?: number; quantity?: number; quantity_shipped?: number; quantity_instock?: number; activity_id?: number; image?: string; }; -
Before the
returnstatement, use the Preact hooks that you imported to determine if an activity item is selected.const ItemActionsContainer = (props: Props) => { const [hideActions, setHideActions] = useState<boolean>(true); if (props.itemSelected?.id) { console.log("Selected: " + JSON.stringify(props.itemSelected)); } useEffect(() => { if (props.itemSelected?.id) { setHideActions(false); } else { setHideActions(true); } }, [props.itemSelected]); return ( -
In the
returnstatement, add a newoj-buttonelement with anonojActionattribute that references theeditproperty.const ItemActionsContainer = (props: Props) => { return ( <div> <oj-button id="createButton" onojAction={props.create}>Create</oj-button> <oj-button id="updateButton" disabled={hideActions} onojAction={props.edit}>Update</oj-button> </div>Save the
ItemActionsContainer.tsxfile. Your code should be similar toItemActionsContainer.tsx.txt -
At the top of the
EditItemDialog.tsxfile, import the modules for the Oracle JET Dialog component, as well as theuseRef,useEffect,MutableRef, anduseStatePreact hooks.import { h } from "preact"; import { useRef, useEffect, useState, MutableRef } from "preact/hooks"; import "ojs/ojdialog"; import { ojDialog } from "ojs/ojdialog"; -
In the
Propstype alias, create the following properties.type Props = { isOpened: boolean; closeDialog: (ref: MutableRef<ojDialog>, type: string) => void; editItem: (data: Partial<Item>, ref: MutableRef<ojDialog>) => void; itemData: Partial<Item>; }; -
In the
returnstatement, replace the existingdivelement with aspanelement that wraps theoj-dialogcustom element.return ( <span> <oj-dialog id="editDialog" ref={editDialogRef as MutableRef<ojDialog>} dialogTitle="Update Item Details" onojClose={closeDialog} cancelBehavior="icon"> <div slot="body"> <oj-label-value labelEdge="inside"> <oj-label for="itemid" slot="label"> Item ID </oj-label> <div id="itemid" slot="value" class="slot-line"> {editFormData?.id} </div> </oj-label-value> <oj-form-layout> <oj-input-text id="name" labelHint="Name" onvalueChanged={onChangeHandler} value={editFormData?.name}></oj-input-text> <oj-input-text id="price" labelHint="Price" onvalueChanged={onChangeHandler} value={editFormData?.price}></oj-input-text> <oj-input-text id="short_desc" labelHint="Description" onvalueChanged={onChangeHandler} value={editFormData?.short_desc}></oj-input-text> </oj-form-layout> </div> <div slot="footer"> <oj-button id="submitBtn" onojAction={editItem}> Submit </oj-button> </div> </oj-dialog> </span> ); -
Before the
returnstatement, add the methods that the attribute values in the child custom elements of theoj-dialogcustom element reference. For example, theonChangeHandlermethod is called when anoj-input-textcomponent detects a change through itsonvalueChangedattribute.const EditItemDialog = (props: Props) => { const editDialogRef = useRef<ojDialog>(); const [editFormData, setEditFormData] = useState<Partial<Item>>({}); const onChangeHandler = (event: any) => { if (event.detail.updatedFrom === "internal") { setEditFormData({ ...editFormData, [event.currentTarget.id]: event.detail.value, }); } }; const closeDialog = () => { props.closeDialog(editDialogRef as MutableRef<ojDialog>, "edit"); }; const editItem = () => { console.log("data: " + JSON.stringify(editFormData)); props.editItem(editFormData, editDialogRef as MutableRef<ojDialog>); }; useEffect(() => { setEditFormData(props.itemData); props.isOpened ? editDialogRef.current?.open() : editDialogRef.current?.close(); }, [props.isOpened]); return ( -
Before the declaration of the
EditItemDialogfunction, define anItemtype alias that includes fields for the data that you update and send to the REST service.type Item = { id: number; name: string | undefined; short_desc?: string; price?: number; quantity?: number; quantity_shipped?: number; quantity_instock?: number; activity_id?: number; image?: string; }; const EditItemDialog = (props: Props) => {Save the
EditItemDialog.tsxfile. Your code should be similar toEditItemDialog.tsx.txt
Task 3: Consume the EditItemDialog Component
-
Open the
ActivityItemContainer.tsxfile and import theEditItemDialogcomponent that you created in the last task plus Preact’sMutableRefhook and the Oracle JET module for the Dialog component.import { useState, useCallback, MutableRef, useRef } from "preact/hooks"; import EditItemDialog from "./EditItemDialog"; -
In the
Propstype alias, update the entry fordatato support theanytype forRESTDataProviderand delete or comment out theActivityItemtype that the component no longer uses.type Props = { data?: RESTDataProvider<any, any>; selectedActivity: Item | null; onItemChanged: (item: Item) => void; }; // type ActivityItem = { // id: number; // name: string; // items: Array<Item>; // short_desc: string; // image: string; // }; -
In the
returnstatement, update theItemActionsContainerelement withitemSelectedandeditattribute values. After theCreateNewItemDialogelement, add a new element for theEditItemDialogcomponent that you imported.<div id="container"> <h3>Activity Items</h3> <ItemActionsContainer create={openCreateDialog} itemSelected={activityItemValue} edit={openEditDialog} /> . . . </div> <CreateNewItemDialog isOpened={isCreateOpened} createNewItem={createItem} closeDialog={handleDialogClose} /> <EditItemDialog isOpened={isEditOpened} editItem={editItem} closeDialog={handleDialogClose} itemData={itemData} /> . . . -
Before the
returnstatement, add theopenEditDialogfunction to open the edit dialog and theeditItemfunction to send the updated activity item to the REST service.const openEditDialog = () => { console.log("Item: " + JSON.stringify(itemData)); setIsEditOpened(true); console.log("Edit dialog opened"); }; const editItem = async (newItemData:Partial<Item>, editDialogRef = useRef<ojDialog>()) => { if (newItemData != null) { const row = { itemId: newItemData.id, name: newItemData.name, price: newItemData.price, short_desc: newItemData.short_desc, }; // Create and send request to update row on rest service const request = new Request(`${restServerURLItems}${itemData.id}`, { headers: new Headers({ "Content-type": "application/json; charset=UTF-8", }), body: JSON.stringify(row), method: "PUT", }); const response = await fetch(request); const updatedRow = await response.json(); // Create update mutate event and call mutate method // to notify dataprovider consumers that a row has been // updated const updatedRowKey = itemData.id; const updatedRowMetaData = { key: updatedRowKey }; props.data?.mutate({ update: { data: [updatedRow], keys: new Set([updatedRowKey]), metadata: [updatedRowMetaData], }, }); } // End if statement console.log("Edited item"); editDialogRef.current?.close(); };Save the
ActivityItemContainer.tsxfile. Your code should be similar toActivityItemContainer.tsx.txt
Task 4: Test the Code and Update a Record
-
In the terminal window, change to the
JET-Virtual-DOM-appdirectory and run the virtual DOM app.npx ojet serve - In the browser, view the dynamic changes in your virtual DOM app.
- In the virtual DOM app, click the Baseball activity, and then click the SureFire Ball (Set of 4) item.
-
Click the Update button.
The Update Item Details dialog pops up.
-
Change the price from
20.5to21and click Submit.The section refreshes and the price of the item has been updated.

- Close the browser window or tab that displays your running virtual DOM app.
- In the terminal window, press Ctrl+C, and if prompted, enter
yto exit the Oracle JET tooling batch job.
Next Step
Proceed to the next tutorial in this module.
This tutorial is part of the module CRUD Operations Using a REST Service.
- Fetch Data from the REST API in Oracle JET
- Create a Form to Create Data Records in an Oracle JET Virtual DOM App
- Update Data Records in an Oracle JET Virtual DOM App
- Delete Data Records in an Oracle JET Virtual DOM App
You can return to the virtual DOM learning path’s main page to access all the modules on building virtual DOM apps.
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Update data records in an Oracle JET virtual DOM app
F70629-04