(
resource: Resource,
propertyURL: string,
/** Saves the resource when the resource is changed, after 100ms */
opts: useValueOptions = {},
)
| 223 | * ``` |
| 224 | */ |
| 225 | export function useValue( |
| 226 | resource: Resource, |
| 227 | propertyURL: string, |
| 228 | /** Saves the resource when the resource is changed, after 100ms */ |
| 229 | opts: useValueOptions = {}, |
| 230 | ): [JSONValue | null, setValue] { |
| 231 | const { |
| 232 | commit = false, |
| 233 | validate = true, |
| 234 | commitDebounce = 100, |
| 235 | handleValidationError, |
| 236 | } = opts; |
| 237 | const [val, set] = useState<JSONValue>(null); |
| 238 | const store = useStore(); |
| 239 | const debounced = useDebounce(val, commitDebounce); |
| 240 | const [touched, setTouched] = useState(false); |
| 241 | |
| 242 | // Try without this |
| 243 | // When a component mounts, it needs to let the store know that it will subscribe to changes to that resource. |
| 244 | // useEffect(() => { |
| 245 | // function handleNotify(updated: Resource) { |
| 246 | // // When a change happens, set the new Resource. |
| 247 | // set(updated.get(propertyURL)); |
| 248 | // } |
| 249 | // store.subscribe(subject, handleNotify); |
| 250 | |
| 251 | // return () => { |
| 252 | // // When the component is unmounted, unsubscribe from the store. |
| 253 | // store.unsubscribe(subject, handleNotify); |
| 254 | // }; |
| 255 | // }, [store, resource, subject]); |
| 256 | |
| 257 | // Save the resource when the debounced value has changed |
| 258 | useEffect(() => { |
| 259 | // Touched prevents the resource from being saved when it is loaded (and not changed) |
| 260 | if (commit && touched) { |
| 261 | // This weird async wrapping is needed to use await in a react hook. |
| 262 | async function save() { |
| 263 | try { |
| 264 | setTouched(false); |
| 265 | await resource.save(store, store.getAgent()); |
| 266 | } catch (e) { |
| 267 | store.handleError(e); |
| 268 | } |
| 269 | } |
| 270 | save(); |
| 271 | } |
| 272 | }, [JSON.stringify(debounced)]); |
| 273 | |
| 274 | /** |
| 275 | * Validates the value. If it fails, it calls the function in the second |
| 276 | * Argument. Pass null to remove existing value. |
| 277 | */ |
| 278 | async function validateAndSet(newVal: JSONValue): Promise<void> { |
| 279 | if (newVal == null) { |
| 280 | // remove the value |
| 281 | resource.removePropVal(propertyURL); |
| 282 | set(null); |
no test coverage detected