Add updateResouce method to ResourceContainer
authorFrank Bessou <frank.bessou@logilab.fr>
Thu, 11 May 2017 10:50:57 +0200
changeset 194 968657b3534c
parent 193 3c032c1c33c8
child 195 179d532e517a
Add updateResouce method to ResourceContainer This method should be called by children components to tell its container that the resource should be updated. The rawData argument can be given to provide the new resource's data. Its main purpose is to be used by edition and creation forms to avoid seeing outdated data after submission.
src/components/Resource.js
--- a/src/components/Resource.js	Thu May 11 10:29:13 2017 +0200
+++ b/src/components/Resource.js	Thu May 11 10:50:57 2017 +0200
@@ -1,11 +1,12 @@
 import * as React from 'react';
 import hypermediaClient from '../services/hypermedia';
 import {PropTypes} from 'prop-types';
+import {merge} from 'lodash/object';
 
 import {appendPath} from '../utils';
 import {EntityAttributes, EntityForm, EntityMeta, RelatedResources} from './Entity';
 import {PropTypesResourceModel} from '../model';
-import {PropTypeJsonaryWrapper} from '../jsonaryutils';
+import {PropTypeJsonaryWrapper, mapToSchema} from '../jsonaryutils';
 import {ActionsDropDown, CollectionView} from './BaseViews';
 
 export class ResourceContainer extends React.Component {
@@ -13,6 +14,7 @@
         super(props);
         this.state = this.getInitialState();
         this.hypermediaClient = hypermediaClient;
+        this.updateResource = this.updateResource.bind(this);
     }
 
     getInitialState() {
@@ -23,6 +25,7 @@
         return this.hypermediaClient.getResource(route).then(
             resource => {
                 this.setState({resource: resource});
+                return resource;
             });
     }
 
@@ -38,13 +41,24 @@
         this.initResource(this.props.url);
     }
 
+    updateResource(rawData) {
+        if (rawData !== undefined) {
+            const schema = this.state.resource.data.schemas()[0].data.value();
+            const data = mapToSchema(rawData, schema);
+            this.setState(merge({}, this.state, {resource: {data: data}}));
+            return Promise.resolve(this.state.resource);
+        }
+        this.setState({resource: null});
+        return this.initResource(this.props.url);
+    }
+
     render() {
         if (!this.state.resource) {
             return <div>Loading...</div>;
         }
         const Component = this.props.component;
         const childProps = this.props.childProps || {};
-        return <Component {...childProps} resource={this.state.resource} />;
+        return <Component {...childProps} updateResource={this.updateResource} resource={this.state.resource} />;
     }
 
 }