Ionic 3 value binding Geolocation

2019-07-08 21:29发布

问题:

ERROR TypeError: Cannot set property 'items' of null

This is the result of:

</ion-card>
<button ion-button round outline 
(click)="logEvent($startTrackingButton)">Start tracking me</button>
<ion-card>
<ion-item>
<h2>Locations:</h2>
<ion-list no-lines>
<h3 ion-item *ngFor="let item of items" (click)="itemSelected(item)">
{{ item }}
</h3>
</ion-list>
</ion-item>
</ion-card>
</ion-content>

(In Component.html), now for its .ts file:

logEvent1(TrackNowButton) {

    /*Initializing geolocation*/

    // onSuccess Callback
    // This method accepts a Position object, 
    // which contains the
    // current GPS coordinates
    var onSuccess = function(position) {
        this.items = ([{
            key: "1", value: {
                Latitude: position.coords.latitude,
                Longitude: position.coords.longitude
            }
        }, {
            key: "2", value: {
                Altitude: position.coords.altitude,
                Accuracy: position.coords.accuracy
            }
        }, {
            key: "3", value: {
                Altitude_Accuracy: position.coords.altitudeAccuracy,
                Heading: position.coords.heading
            }
        }, {
            key: "4", value: {
                Speed: position.coords.speed,
                Timestamp: position.timestamp
            }
        }]);
    };

    // onError Callback receives a PositionError 
    // object
    function onError(error) {
        console.log('code: ' + error.code + '\n' + 'message: ' + error.message + '\n');
    }
    navigator.geolocation.getCurrentPosition(onSuccess, onError);
}

itemSelected(item: string) {
    console.log("Selected Item", item);
}

I hope this is readable... I don´t know what I´m doing wrong in terms of data binding because that's where I think the mistake is... I also believe that there is something wrong with the part in the .ts file, where I wrote: this.items= (...) as I think that the value can´t be bound to the html or something. I´m working on a little program that tracks movements every so often and logs them with the given parameters. Later I want to add Mapbox support but I need to resolve some errors first.

回答1:

The error that you get indicates that this is null. Replace the function assigned to onSuccess by an arrow function. It will use the correct value for this.

var onSuccess = (position: any) => {
    this.items = ([{
        key: "1", value: {
            Latitude: position.coords.latitude,
            Longitude: position.coords.longitude
        }
    }, {
        key: "2", value: {
            Altitude: position.coords.altitude,
            Accuracy: position.coords.accuracy
        }
    }, {
        key: "3", value: {
            Altitude_Accuracy: position.coords.altitudeAccuracy,
            Heading: position.coords.heading
        }
    }, {
        key: "4", value: {
            Speed: position.coords.speed,
            Timestamp: position.timestamp
        }
    }]);
};

You can use JSON.stringify to convert the selected item to a string:

itemSelected(item: any) {
    console.dir(item);
    let str = JSON.stringify(item);
    ...
}

On the other hand, if each item needs to be defined as a string, you can call JSON.stringify for each one in the array.

var onSuccess = (position: any) => {
    this.items = ([JSON.stringify({
        key: "1", value: {
            Latitude: position.coords.latitude,
            Longitude: position.coords.longitude
        }
    }), JSON.stringify({
        key: "2", value: {
            Altitude: position.coords.altitude,
            Accuracy: position.coords.accuracy
        }
    }), JSON.stringify({
        key: "3", value: {
            Altitude_Accuracy: position.coords.altitudeAccuracy,
            Heading: position.coords.heading
        }
    }), JSON.stringify({
        key: "4", value: {
            Speed: position.coords.speed,
            Timestamp: position.timestamp
        }
    })]);
}


回答2:

You just need to initialize your array as shown below.

items:any = [];

After that you can push the values like so:

this.items.push({ key: "1", value: { Latitude: 
    position.coords.latitude, Longitude: position.coords.longitude });


回答3:

Your error indicates that your code is hitting onSuccess method.

You can assign this to another variable to be used when the callback function is called. Keep in mind that call backs don't always execute in the context of the class you are in. Therefor this can be undefined.

Here is how you need to do it:

logEvent1(TrackNowButton) {
  let self = this;
  onSuccess = (position)=>{
     self.items = [
         {key : '1', value : {} }
         {key : '2', value : {} }
         {key : '3', value : {} }
      ]
  }
  let onError = (error)=>{
     console.log('code: ' + error.code + '\n' + 'message: ' + error.message + '\n');
  }
  navigator.geolocation.getCurrentPosition(onSuccess, onError);
}