Rick Hedin (10) [Avatar] Offline
#1
And I figured out why. From the Nativescript documentation:


constructor
new Observable(): Observable
Defined in data/observable/observable.d.ts:72
Please note that should you be using the new Observable({}) constructor, it is obsolete since v3.0, and you have to migrate to the "data/observable" fromObject({}) or the fromObjectRecursive({}) functions.

Returns Observable
Rick Hedin (10) [Avatar] Offline
#2
Furthermore, two things.

1. New is not needed when doing fromObject (but it seems to be ignored)
2. All the data members that you want to watch have to be mentioned in the object you pass to fromObject. Otherwise the binding isn't created.
Plus they have to be given a default of the correct type. Otherwise in the case of an object like a date, the system tries to dereference it:
CONSOLE ERROR file:///app/tns_modules/tns-core-modules/trace/trace.js:165:30: Binding: Binding error while setting property date of DatePicker(smilie@file:///app/views/scrapbook-page.xml:6:9;: TypeError: undefined is not an object (evaluating 'value.getFullYear')
Rick Hedin (10) [Avatar] Offline
#3
Make up your mind! Is args.object a reference to the button object, or to the page object?

?   args.object is a reference to the button object

Mike Branstein; Nick Branstein. NativeScript in Action MEAP V13 (Kindle Location 3420). Manning Publications Co.. Kindle Edition.

In listing 8.13, we are using a button tap event to access the binding context the scrapbook page. When a tap event is handled, the handler passes a reference to the page via the object property, so args.object is a reference to the page.

Mike Branstein; Nick Branstein. NativeScript in Action MEAP V13 (Kindle Locations 3423-3425). Manning Publications Co.. Kindle Edition.
mikebranstein (12) [Avatar] Offline
#4
Rick - thank you for identifying a few errors we missed in our last round of changes!

  • We thought we had fixed all of the Observable({}) code snippets, but must have missed one. Thank you! Check out https://github.com/mikebranstein/NativeScriptInAction/blob/master/Chapter8/PetScrapbook/app/views/home-page.js, which has the updated code for listing 8.7. I'm submitting an update to the book text and listings this evening.

  • For the value.getFullYear error, could you point me to a page or listing number so we can adjust it?

  • Thank you for pointing out the text around listing 8.13 - I've updated that listing in the text and will be submitting it this evening.


  • If you find anything else, please let us know!
    Rick Hedin (10) [Avatar] Offline
    #5
    Hi, Mike.

    Replying to your 2nd bullet point. Looking back over what I did, it seems to be associated with Listing 8.13 Accessing data bound properties on the views\scrapbook-page.js

    Below is the relevant code. Notice my contortions in the onTap function, trying to figure out what was happening. The answer to your question is in the onLoaded function.

    var observable = require("data/observable");
    
    exports.onLoaded = function(args) {
        var page = args.object;
        var scrapbook = observable.fromObject({
            title: '',
            genders: ["Female", "Male", "Other"],
            date: new Date(),  // If you comment out this line, you will get the error message 
                               // about not being able to dereference the date property.
                               // Binding error while setting property date of 
                               // DatePicker(8)@file:///app/views/scrapbook-page.xml:6:9;: 
                               // TypeError: undefined is not an object (evaluating 'value.getFullYear')
            gender: 0,
            calcAge: function(birthDate){           var now = Date.now();
                var diff = Math.abs(now - birthDate) / 1000 / 31536000;
                return diff.toFixed(1);
            }
        });
        // Apparently, fromObject 1) does not require a new.  2) needs to have 
        // all the data items mentioned.
        
        page.bindingContext = scrapbook;
    };
    
    exports.onTap = function(args) {
        var page = args.object;
        // console.dir(args.object);
        var scrapbook = page.bindingContext; 
        // console.log('page.bindingContext:'); 
        // console.dir(page.bindingContext);    
        console.log("You have made " + scrapbook.title);
        // console.log(scrapbook.genders);
        // console.dir(scrapbook.genders);
        // console.log(scrapbook.gender);
        console.log("Age: " + scrapbook.date.toLocaleDateString());
        // console.log(`gender index = ${scrapbook.gender}`);
        console.log("Gender selected:" + scrapbook.genders[scrapbook.gender]); 
    }
    


    Regards, Rick