Nativescript: closeCallback not firing

Created on 16 Jun 2016  路  9Comments  路  Source: NativeScript/NativeScript

Hello,

I am having trouble with implementing a modal view. Here is my code:

//in the main form
function showDOB() {
    page.showModal('widgets/datepicker/datepicker', model.customer.DOB, function(dt) {
        alert(dt);
        model.set('customer.DOB', dt);
    }, true);
}

//in the modal form
var closeCallback;
var modal;

function onShownModally(args) {
    var dt = new Date(args.context);

    model.set('year', dt.getFullYear());
    model.set('month', dt.getMonth() + 1);
    model.set('day', dt.getDate());

    closeCallback = args.closeCallback;
}

function onLoaded(args) {
    var page = args.object;
    page.bindingContext = model;
}

function done() {
    var value = '1/28/1969'; //test
    closeCallback(value);
}

when the done function is invoked, the modal is closed but the closeCallback never gets executed.

I am using iOS, NativeScript 2.0.0, and tns-core-modules 2.0.1

Thank you.

question

All 9 comments

Hello @dpdragnev

have you reffered your onShownModallyfunction in your xml! lie this

<Page xmlns="http://schemas.nativescript.org/tns.xsd" showingModally="onShownModally">

Also have you exported your functions

exports.onShownModally = onShownModally;

yes, this is my xml:

<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onLoaded" shownModally="onShownModally">
  <DockLayout>
      <StackLayout>
        <DatePicker year="{{ year }}" month="{{ month }}" day="{{ day }}" />
        <Label text="Done" tap="done" class="done" />
      </StackLayout>
  </DockLayout>

</Page>

I noticed that in your example you bind it to showingModally not shownModally. Which one is the correct event?

I am experiencing the same problem.

Error

TypeError: closeModal is not a function

Modal.js

var observable = require("data/observable").Observable;
var frameData = new observable();
var closeModal;

var bindFrame = function(args){
  frame = args.object;
  frame.bindingContext = frameData;
  closeModal = args.closeCallback;
  console.log(typeof args.closeCallback); // Returns "JS: undefined"
};

module.exports = {
  bindFrame: bindFrame,
  submitQuantity: function(args){
    closeModal(); 
  }
};

Modal.xml

<Page showingModally="bindFrame">
  <ScrollView>
    <StackLayout class="container">
      <button text="Submit" tap="submitQuantity"/>
    </StackLayout>
  </ScrollView>
</Page>

@dpdragnev your logic looks as it should be but I was not able to fully reproduce your project as the view-modle you are using is not present. So I created a similar project that demonstrates a scenario very close to yours. Take a look at this repository where a working closeCallBack was implemented : https://github.com/NickIliev/NativeScript-modalPage-example

I hope that will help you out your project. If you need further assistance do not hesitate to contact me but please provide some sample solution which I can reproduce.

@kadjei

Try using shownModally as @dpdragnev does.

@NickIliev Thank you for the example. I will try that and will let you know how it goes.

This is really strange. Your code runs correctly, but in my solution the callback does not fire. The only difference if that the modal form is in a different folder.

It turned out that the problem was not in the callback. The issue was in my view model. I was binding my UI to a complex object (customer object), but when I inject it into the page's context I did not set it to be an observable object. So, when the property changed, the UI did not update which I attributed to a problem with the callback.

To solve it, I had to set the customer object as an observable:

model.set('customer', new Observable(customer_object));

In the web world, the child object will inherit the observable behavior of the parent (model -> customer), but it turns out that in NativeScript this behavior must be specified explicitly.

I've noticed what I think is a bug.

There are currently 5 different ways listed to call showModal in the API Reference, however 3 of them are deprecated.

  • Using the __deprecated__ method successfully calls the closeCallback when the modal is closed;

    showModal(moduleName, context, closeCallback, fullscreen, animated, stretched);
    
  • Using the __suggested__ method fails to call closeCallback when the modal is closed;

    showModal(moduleName, modalOptions);
    

There's also an inconsistency when working with the context via the suggested method oniOS and Android. On Android you can still create an xml binding as normal, but on iOS you have to access the properties one level down.

  • Android binding via __suggested__ method;
    xml <Label text="{{ text }}" />
  • iOS binding via __suggested__ method;
    xml <Label text="{{ context.text }}" />

Here's a Playground showing the issues.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings