How to Clear Contents of an observableArray That was Populated from Previous Visits to a View

I have a Single Page Application that uses knockout for the data binding. The CAApproval.html view in my single page application has an observeablearray named AllCertificates in the viewmodel code. It populates fine on the page. When you navigate away from the view by clicking a link in the navigation.html part of the page and then return to CAApproval page, the values from the previouse visit are still in the AllCertificates observableArray and therefore are displayed on the CAApproval view.

I need to clear the contents of the AllCertificates observablearray each time a user returns to the CAApproval page that uses that observablearray so that if a user leaves the page and comes back, the contents of the observablearray are null, and therefore no data is displayed on the screen. Here are the highlights of my viewmodel code-

define(['services/logger', 'durandal/system', 'durandal/plugins/router', 'services/CertificateDataService','controls/Lucas'],

       function(logger, system, router, CertificateDataService) {
        var allCertificates = ko.observableArray([]);

    var activate = function () {
            // go get local data, if we have it
            return SelectAllCerts(),SelectMyCerts(), GetCertificateDetails(), GetDDABankNums();
            };
        var vm = {
            activate: activate,
            allCertificates: allCertificates,
    SelectAllCerts: SelectAllCerts

        });

    return vm;

    function SelectAllCerts() {
                return CertificateDataService.getallCertificates(allCertificates);
        }
    });

How do I clear the contents of an observablearray each time the page a user comes to that page (NOT when navigating within the page itself, only clear the observablearray when the user comes from a seperate page)?

Answers


Just set it equal to nothing (allCertificates([])) in your activate function, which is called each time your view model loads -

function(logger, system, router, CertificateDataService) {
    var allCertificates = ko.observableArray();

var activate = function () {
    allCertificates([]);
    // go get local data, if we have it
    return SelectAllCerts(),SelectMyCerts(), GetCertificateDetails(), GetDDABankNums();
};

var vm = {
    activate: activate,
    allCertificates: allCertificates,
    SelectAllCerts: SelectAllCerts
});

Also knockout observableArray has interesting methods. Call removeAll to clear all items. Look at official site observable array manual.

self.mycertificates = ko.observableArray(['C1', 'C2']);  
self.mycertificates.removeAll();

For Jeremy T (not enough space in comment). First reason and absolutely enough for me is existence of publicly available API for desired purpose.

But to estimate performance you can check source. "observableArray" is also "observable" with additional functions injected into object.

So initialization looks like this:

ko.observableArray = function (initialValues) {
    initialValues = initialValues || [];

    if (typeof initialValues != 'object' || !('length' in initialValues))
        throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");

    var result = ko.observable(initialValues);
    ko.utils.extend(result, ko.observableArray['fn']);
    return result.extend({'trackArrayChanges':true});
};

ko.observable = function (initialValue) {
    var _latestValue = initialValue;

    function observable() {
        if (arguments.length > 0) {
            // Write

            // Ignore writes if the value hasn't changed
            if (!observable['equalityComparer'] || !observable['equalityComparer'](_latestValue, arguments[0])) {
                observable.valueWillMutate();
                _latestValue = arguments[0];
                if (DEBUG) observable._latestValue = _latestValue;
                observable.valueHasMutated();
            }
            return this; // Permits chained assignments
        }
        else {
            // Read
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
            return _latestValue;
        }
    }
    if (DEBUG) observable._latestValue = _latestValue;
    ko.subscribable.call(observable);
    observable.peek = function() { return _latestValue };
    observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); }
    observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }
    ko.utils.extend(observable, ko.observable['fn']);

    ko.exportProperty(observable, 'peek', observable.peek);
    ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated);
    ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate);

    return observable;
}

And remove all elements looks like this:

'removeAll': function (arrayOfValues) {
        // If you passed zero args, we remove everything
        if (arrayOfValues === undefined) {
            var underlyingArray = this.peek();
            var allValues = underlyingArray.slice(0);
            this.valueWillMutate();
            underlyingArray.splice(0, underlyingArray.length);
            this.valueHasMutated();
            return allValues;
        }
        // If you passed an arg, we interpret it as an array of entries to remove
        if (!arrayOfValues)
            return [];
        return this['remove'](function (value) {
            return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
        });
    }

Need Your Help

Getting a ReturnValue from cmd.Parameters in c#?

c# asp.net sql parameters

I have just finished converted a vb.net app to c# and one of the lines is to get @ReturnValue from the parameter.

Android shared element transition between two activities does not work

android android-design-library floating-action-button

In my app I'm trying to use the newly introduced element sharing between activities. Everything works like a charm if the shared element is with fixed position (e.g. android:layout_gravity="top") b...