Changes in Sidecar model not reflected in Sugar bean

I have a requirement where a field called resource_rate_actual has be set equal to one of several fields, depending on the value selected in a dropdown. I've set it up in record.js view controller like this:

initialize: function (options) {
        this._super('initialize', [options]);
        this.model.on('change:resource_type', this.resource_type_changed, this);
    }, 
resource_type_changed: function(){
        if(!_.isUndefined(this.model.get('resource_type'))) {
            switch (this.model.get('resource_type')) {
                case 'Project Manager':
                    this.model.set('resource_rate_actual', this.model.get('project_manager_rate_c'));
                    break;
                case 'Engineer':
                    this.model.set('resource_rate_actual', this.model.get('engineer_rate_c'));
                    break;
            }
        }
    },

This works well to automatically set the resource_rate_actual field on the front end, depending on whether a Project Manager or an Engineer is selected in the dropdown. But, when the record was saved, the value in the resource_rate_actual field did not get saved to the database. In order to save it, I had to set up a before_save logic hook to set the value of $bean->resource_rate_actual on the back end with this code:

switch ($bean->custom_rate) {
                case 'Project Manager':
                    $bean->resource_rate_actual = $bean->project_manager_rate_c;
                break;
                case 'Project Manager':
                    $bean->resource_rate_actual = $bean->project_manager_rate_c;
                    break;

}

With this logic hook, the record was saved as displayed on the front end.

My question is, why is it necessary to set the value of resource_rate_actual both on the front end and on the back end? As I understand it, a Sidecar model is a JS object that represents the Sugar Bean, and any changes to the model should be reflected in the bean. Is this not correct?

  • Hi Yury Voloshin,

    You are right that any changes to the model are reflected in the bean. I never used logic hooks to manage my frontend and backend separately. I guess the issue is maybe this.model.set is executing before this.model.get. Well, it also should not happen because inner code executes first.

    Please try this:

    var pro_manager = this.model.get('project_manager_rate_c');

    this.model.set('resource_rate_actual', pro_manager);

     

    One more thing is that if you are setting these values for the creation of the new record then add the same code for the CreateView as well in create.js file. Otherwise, it will only work just for the edit/save not for the create/save.

     

     

  • From memory you would need to have the field in the view to be able to save the value from the UI. I believe you should be able to use the keyword "related_fields" on the php view to have the field available in the js view without seeing it in the UI.

    Try it out and is if that works.

    An alternative (possibly better) is to see if you can achieve this exact change without customising the code, just with Sugar Logic and/or Dependencies

    Hope it helps

    --

    Enrico Simonetti

    Sugar veteran (from 2007)

    www.naonis.tech


    Feel free to reach out for consulting regarding:

    • API Integration and Automation Services
    • Sugar Architecture
    • Sugar Performance Optimisation
    • Sugar Consulting, Best Practices and Technical Training
    • AWS and Sugar Technical Help
    • CTO-as-a-service
    • Solutions-as-a-service
    • and more!

    All active SugarCRM certifications

    Actively working remotely with customers based in APAC and in the United States

  • You don't need both, you can do it in the controller OR in the logic hook.

    In your case I would choose the logic hook but it is a personal choice, I think it is cleaner and less dependent on the interface, but I'm old-school-PHP.

    I think the issue with the controller is that the interface tracks what has changed and then saves only those fields, because your field in not in the view it is not seen as changed.
    Try seeing if the changed fields include it by printing the changed objects keys in your console:

    changed = Object.keys(self.model.changedAttributes(self.model.getSynced()));
    console.log(changed);

    You could dig deep into the sidecar bean sidecar/src/data/bean.js and see if you can somehow push that field into the changed attributes... but I think you would be digging VERY deep and for little gain (again, I'm old-school-PHP).

    If you still want to do it from the controller I suggest you try one more thing: do it in silent mode, that way - I think - it should update regardless of whether it is in the interface or not (though you would need to test my theory). BUT it will update BEFORE the user clicks Save and regardless of whether they save or not, so again, I think the logic hook is your best route...


    To update in silent mode your code would look like:

    this.model.set('resource_rate_actual', this.model.get('project_manager_rate_c'),{silent: true});

    and similarly for your other case in the switch statement.

    Hope this helps,

    FrancescaS

  • Thank you Maryam! Breaking up this.model.set and this.model.get into two statements instead of one actually worked and now the record is saved with the logic hook deactivated. This is strange because having them as one statement works well in other view controllers. But in any case, now I'm able to remove the logic hook.