Access custom properties using the UserViewModel

The UserViewModel, which is the global view model that contains a shopper’s profile information, provides access to any custom profile properties you have created via the dynamicProperties observable array.

You can write custom widgets to retrieve the values of custom profile properties from this array, and also set the values of any custom properties you have created.

Get a custom profile property via the UserViewModel

To access a custom profile property from within a widget, you first create a widget-level observable in the widget’s JavaScript file and then assign a value to that observable after retrieving it from the dynamicProperties array. In the following example, we assume that two custom profile properties have been created, age and nickname.

// Create the widget-level observables
age : ko.observable(),
nickname : ko.observable(),

// Iterate over the dynamicProperties array and assign the value of the property
// with id = age to the age observable. Repeat for id = nickname.
for (var i=0; i< widget.user().dynamicProperties().length; i++){
        if (widget.user().dynamicProperties()[i].id() == 'age') {
          widget.age(widget.user().dynamicProperties()[i].value());
        } else if (widget.user().dynamicProperties()[i].id() == 'nickname') {
          widget.nickname(widget.user().dynamicProperties()[i].value());
        }
}

At this point, you can bind the widget-level observables to UI components defined in the widget’s template. For example, this code snippet binds the age and nickname observables to text boxes in the widget’s UI.

<div id="dyn-prop">
    <b>Age:</b><input type="text" name="age" id="CC-dyn-prop-age"
        aria-required="true" data-bind="value: age" ><br>
    <b>Nickname:</b><input type="text"  name="nickname" id="CC-dyn-prop-nickname"
        aria-required="true" data-bind="value: nickname" ><br>
</div>

This code results in a UI that displays two text boxes that have the labels Age and Nickname and are populated with the current values of the age and nickname observables.

Set a custom profile property via the UserViewModel

To set the value of a custom property, your widget must update the dynamicProperties array in the UserViewModel using the current value of the widget-level observable. For example, the code below updates the dynamic property with id=age to the value of the age observable.

for (var i=0; i< widget.user().dynamicProperties().length; i++){
    if (widget.user().dynamicProperties()[i].id() == 'age') {
        widget.user().dynamicProperties()[i].value(widget.age());
            break;
    }
}

To propagate the change in the view model to the server side, the handleUpdateProfile function of the UserViewModel must be called. This function detects modifications in the observables of the UserViewModel and triggers a call to the updateProfile REST endpoint to update the data on the server. Typically, the process of making this call is triggered via clicking a Save button on the page. In the code sample below, taken from the customerProfileDetails.template for the Customer Profile widget, the Save button has a click binding that calls the widget.handleUpdateProfile() method. This method publishes a PubSub event to the USER_PROFILE_UPDATE_SUBMIT topic which, in turn, triggers a call to the handleUpdateProfile() method in the UserViewModel.

<!-- Define the Save and Cancel buttons -->
<button class="cc-button-primary col-sm-2 col-xs-12 pull-right
        cc-customer-profile-button" id="CC-customerProfile-save"
        data-bind="click: handleUpdateProfile,
        event: { mousedown: handleMouseDown, mouseup: handleMouseUp}">
  <span data-bind="widgetLocaleText: 'buttonSave'"></span>
</button>
<button class="cc-button-secondary col-sm-2 col-xs-12 pull-right
        cc-customer-profile-button" id="CC-customerProfile-cancel"
        data-bind="click: handleCancelUpdate,
        event: { mousedown: handleMouseDown, mouseup: handleMouseUp}">
  <span data-bind="widgetLocaleText: 'buttonCancel'"></span>
</button>

Note that the widget.handleUpdateProfile() method is defined in the Customer Profile widget’s customerProfile.js file and it looks like this:

// Handles User profile update
widget.handleUpdateProfile = function () {

  if(widget.isUserProfilePasswordEdited()) {
    widget.user().isPasswordValid();
  }

  // Sends a PubSub message for the update
  $.Topic(PubSub.topicNames.USER_PROFILE_UPDATE_SUBMIT).publishWith(
            widget.user(),
            [{message: "success"}]
  );
};