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"}]
);
};