0
votes

Simple requirement - A knockout observable array in my view model which needs to be populated in a datacontext module. 2 different modules is the core of the problem.

The basic problem is that if a knockout observable is a function, how does one pass it as a parameter and what is the scope of such a variable. Is it global as it is an observable ?The pattern I am using is lifted straight from John Papa's SPA Jumpstart course but does not seem to work for me unless I have missed a bracket or a return statement somewhere. I have tried a number of different combinations.

Using JPs hot towel mvc template but that does not bear reference to my query .

Here is the view model code

define(['dataContext'], function (datacontext) {
    var summary = ko.observableArray();
    var initialise = false;

    var prodModel= {
        activate: activate,
        title: 'Home View',
        summary:summary
    };

    return prodModel;



    //#region Internal Methods
    function activate() {
        if (!initialise)
        {

            initialise = true;
            return getSummary();


        }

        return;

    }
    function getSummary () {

   // Go to the context and populate the observable array
     return   datacontext.getProductionSummary(summary);

    };
    //#endregion
}); 

The following is the datacontext module. The error occurs when trying to assign the javascript array to the knockout observable array in the getProductionSummary method.

It is worth mentioning that I have attempted to use the pushAll utility function as well.

The only thing that populates the observable array is pushing into it directly but even if I do that I do not have the values in the calling viewmodel code as I would expect with an ordinary variable.

 define(['config','services/logger'],
function (config,logger) {


    var getProductionSummary = function (summaryObservableArray) {

     //Call Web API
        var query = breeze.EntityQuery.from('getSummary');
        return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);

    //Yay got the data.. lets play
        function querySucceeded(data) {
            var summary = [];
            for (var i = 0; i < data.results.length; i++) {
                summary.push(data.results[i]);
            }


            return summaryObservableArray(summary);

        }


    };

    var datacontext = { getProductionSummary: getProductionSummary };
    return datacontext;



    // #region Internal functions  

    var manager = createBreezeManager();
    function createBreezeManager () {


        var mgr= new breeze.EntityManager(config.dataEndPoints);

        return mgr;
    };

    function queryFailed(error) {

        logger.log(error.message, null, 'dataContext', true);
    }
//#endregion





});

This is the bit in the view which throws the error

  <!--ko foreach:summary-->
                    <tr>

                        <td><span data-bind="text: summary().Count"></span></td>
                        <td><span data-bind="text: summary().Percentage"></span></td>
                    </tr>
                    <!--/ko-->

The error is

Unable to parse bindings.↵Message: ReferenceError: summary is not defined;↵Bindings value: text: summary().Count
3
The scope of a KO observable variable (or property) is the same as that of any variable (or property). Also, don't forget to explain what "the error" is. - user2246674
Yes, what is the error? But I will also say that returning summaryObservableArray(summary) is meaningless. That's because an observable simple does return this; when written, which in this case will be the window object. - Michael Best
this line var manager = createBreezeManager(); is not executed and manager.executeQuery(query) should throw error. - xdenser
Apologies..the error is Unable to parse bindings.↵Message: ReferenceError: summary is not defined;↵Bindings value: text: summary().Count This is in the view model where I am databinding to summary().Count and summary().Percentage. Breeze is executing as it should. I can see the values being returned I can even see the value in my observablearray in the datacontext but then the binding fails. - shai
I meant the error is in the view ...not the view model. - shai

3 Answers

0
votes

@xdenser has correctly identified a most significant problem in your code.

return datacontext;
...
// never executed because you returned; manager is undefined.
var manager = createBreezeManager();

You didn't state the error. Our bet is that you get a "manager undefined" error when you call getProductionSummary in your viewmodel. Move the line up (preferably near the top of datacontext) and you'll be fine:

var manager = createBreezeManager();
...
return datacontext;

It all seems a bit tortured. Why not do away with createBreezeManager and just begin as follows?

var manager = new breeze.EntityManager(config.dataEndPoints);

You also have a somewhat over-complicated querySucceeded which could be as simple as this:

function querySucceeded(data) { summaryObservableArray(data.results); }
0
votes

data-bind="text: summary().Count == WRONG data-bind="text: Count== RIGHT

Duh.. Got thrown by the error statement. But thanks all for responding.

0
votes
<!--ko foreach:summary-->
         <tr>
            <td><span data-bind="text: Count"></span></td>
            <td><span data-bind="text: Percentage"></span></td>
         </tr>
<!--/ko-->

this is correct view

inside foreach binding context is array item. still do not understand how your dataContext module works. suspect you are showing not actual code.