Reputation: 1344
I am getting the following error:
Property 'subscribe' does not exist on type 'void'.ts(2339)
when I try to use my AutoLocate function (below) by subscribing to it thusly:
this.AutoLocate().subscribe(data => { this.GotLoc = data});
Below is the AutoLocate function and also a GetAddress function that I use to get a complete model that uses Lat/Long and Address.
AutoLocate() {
let AutoLocatedLocation: PlaceLocation;
if(!Capacitor.isPluginAvailable('Geolocation')) {
this.Alert.create({header: 'Location Service Error', message: 'Could not initialize Location Services! Please call support!'})
return;
}
Plugins.Geolocation.getCurrentPosition().then(GeoPosition => {
return this.coordinates = {lat: GeoPosition.coords.latitude, lng: GeoPosition.coords.longitude};
}).then(coords => {
this.GetAddress(coords.lat, coords.lng).subscribe(res => {
this.Address = res;
return AutoLocatedLocation = { lat: coords.lat, lng: coords.lng, address: res};
});
}).catch(error => {
this.Alert.create({header: 'Location Service Error', message: 'Could not initialize Location Services! Please call support!'})
console.log("Location: ", error);
});
}
private GetAddress(lat: number, lng: number) {
return this.http.get<any>(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${environment.googleMapsAPIKey}`)
.pipe(map(geoData => {
if (!geoData || !geoData.results || geoData.results.length === 0) {
return null;
}
return geoData.results[0].formatted_address;
}));
}
What am I doing wrong?
Upvotes: 0
Views: 315
Reputation: 31125
It appears you're mixing Promises with Observables. Moreover the AutoLocate()
function isn't returning anything at the moment.
You could either convert observable to promise or vice-versa. I'd do the former using RxJS from
function. Then you could apply the necessary operators to transform the data
import { of, from, NEVER } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
AutoLocate(): Observable<any> { // <-- return type `Observable`
let AutoLocatedLocation: PlaceLocation;
if(!Capacitor.isPluginAvailable('Geolocation')) {
this.Alert.create({header: 'Location Service Error', message: 'Could not initialize Location Services! Please call support!'})
return NEVER; // <-- use RxJS `NEVER` constant - it'll never emit
}
return from(Plugins.Geolocation.getCurrentPosition()).pipe( // <-- return the observable
switchMap(GeoPosition => {
const coords = { lat: GeoPosition.coords.latitude, lng: GeoPosition.coords.longitude };
this.coordinates = coords; // <-- why is this needed though?
return this.GetAddress(coords.lat, coords.lng).pipe(
map(res => {
this.Address = res; // <-- again, is this needed here?
return ({ ...coords, address: res }); // spread operator `...` retains old values while adding/modifying other values
})
)
}),
catchError(error => {
this.Alert.create({header: 'Location Service Error', message: 'Could not initialize Location Services! Please call support!'});
return of(error); // <-- `catchError` must return an observable
})
);
}
Breakdown:
from
function to convert the promise to observableNEVER
constant to not emit to the subscription instead of a plain JS return;
map
operator to transform the emission to the required formatswitchMap
operator to map from one observable to anothercatchError
operator to catch and trigger an alert. Note that catchError
must return an observable. of
function is used for that function.Upvotes: 3