0

I have a zone related problem, and i can't get it working. i'm new to angular but have some basic javascript understanding.

So what is the problem, i can not get the view updated.

Im using a third party library for ionic BLE, and use this in a provider

providers/communication-controller.ts

set_ble_tolisten(){
    //subscribe to receive notification, rx channel
    console.log('  set_ble_tolisten' + NgZone.isInAngularZone());
    this.ble.startNotification(this.peripheral_object.id, 
    this.TRANSPARANT_SERVICE, this.TX_CHARACTERISTIC).subscribe(
        (data) => this.handlereceiveddata(data),
        () => console.log('Unexpected Error', 'Failed to subscribe for 
            temperature changes')
    )
}

ble_communication_controller(port,command,payload,payloadsize,
callback) 
{
    //create buffer
    var BLE_Sendbuffer= new Int8Array(payloadsize+10);
    var package_index = 0;
    this.generatePacketID();

    this.ble_send_que.push({
        "packetid" : this.packetid,
        "action" :   callback
    });

    //Generate send message
    BLE_Sendbuffer[ some data]

    //send message
    this.ble.write(this.peripheral_object.id,this.TRANSPARANT_SERVICE, 
    this.RX_CHARACTERISTIC,BLE_Sendbuffer.buffer).then(
        () => console.log('ble message send'),
        e => console.log('ble oops')
    );
}

handlereceiveddata(buffer:ArrayBuffer){
    var int8View = new Int8Array(buffer);
    var ReceivedPacketID = 0;
    console.log('handlereceiveddata ' + NgZone.isInAngularZone());

    //first check the header
    if( ((int8View[0] * 0x100) + int8View[1]) === this.HEADER)
    {
        //retrieve packetid from received packet
        ReceivedPacketID = ((int8View[2] * 0x100) + int8View[3]);
        if(ReceivedPacketID === 0) {
            console.log('orgin io or rs232');
     } else {
        //find function based on packetid, and execute
        let index_findresult = this.ble_send_que.findIndex(value => 
        value.packetid  === ReceivedPacketID);

        if(index_findresult != -1)
        {
            this.ble_send_que[index_findresult].action(int8View);
        }
        //remove object from array
        this.ble_send_que.splice(index_findresult, 1);
      }
}

set_ble_tolisten() is called to subcribe on the promise.When data is received handlereceiveddata() is called.

To transmit data ble_communication_controller() is called, this function accepts a callback, which is stored. When the ble device response, the handlereceivedata() is called. This then call the callback which is stored a the ble_communication_controller() call

I created a page, configuration, this contains a ts a html and scss file

the configuration.ts

ionViewDidEnter() {
    this.communicationController.set_ble_tolisten();
   this.sync_device_gui('IO-1');
}

sync_device_gui(port){
    console.log('call in zone ' + NgZone.isInAngularZone());
    var io_port = 0;
    if(port === ‘IO-1')
    {
        io_port = 0x05;
    }

    if(port === 'IO-2')
    {
        io_port = 0x06;
    }

    this.communicationController.ble_communication_controller(io_port,
    GET_IO_STATE,0x00,0,this.update_state_gui);
}

update_state_gui(data){
    //rule below added as explained in first comment (location ngzone.run).
    this.zone.run(() => {
        console.log('repsonse in zone ' + NgZone.isInAngularZone());
        console.log('io port state ' + data);

        console.log('repsonse in zone ' + NgZone.isInAngularZone());
        if(data[8] == 0){
            this.relay_1_toggle = true;
            this.relay_2_toggle = true;
            console.log('state is false set :'+ this.relay_1_toggle + ' 
            state :' +    this.relay_2_toggle );
        }

        if(data[8] == 1){
            this.relay_1_toggle = false;
            this.relay_2_toggle = false;
            console.log('state is true set :'+ this.relay_1_toggle + ' 
            state :' +    this.relay_2_toggle );
       }
     //rule below added as explained in first comment.(location ngzone.run).
    });
       //ruke below added as explained in first commen. (location markForCheck())
       this.cd.markForCheck();



}

when the page is loaded, ionViewDidEnter is called, the problem is that update_state_gui is called from the provider. the data receives in this function. isInAngularZone, tells me that it is false, out of zone. The relay_1_toggle and relay_2_toggle are toggle button in html.

And the get not updated, i tried ngzone.run or a timeout and markForCheck(). but it does not work.

Thanks for your help

  • Can you share the code where you are trying to use zone or cdr manually? Also why did you use custom library vs native plugin? – Sergey Rudenko Oct 10 '18 at 06:16
  • sorry i mean, i used the native plugin, the ble from don coleman, i adjusted the opening post with the location where i added run and markForCheck. i can not place the code in the comment, it is too long – Niels Braspenning Oct 10 '18 at 18:19
  • so are you saying you see console log messages when update_state_gui(data) method is run on page entry? – Sergey Rudenko Oct 10 '18 at 23:27
  • hi, yes the console.log message are as expected (i dont run it in a browser, but as app with xcode on a iphone) . if i get for example 'state is false set : true state : true' and set an interval on page entry, dispaying the same values. then after the function is called, the value are the old value. So only in the function i get the correct values. outide the function not – Niels Braspenning Oct 12 '18 at 04:48
  • Cool, can you share you template code to see bindings you want to be updated? Also please share more if the component code including constructor – Sergey Rudenko Oct 12 '18 at 05:20

0 Answers0