I am using Ionic Native Geolocation plugin from HERE and to start with the example provided so I've done this:
getLocation() {
this.geolocation.getCurrentPosition().then((resp) => {
// resp.coords.latitude
// resp.coords.longitude
}).catch((error) => {
console.log('Error getting location', error);
});
let watch = this.geolocation.watchPosition();
watch.subscribe((data) => {
// data.coords.latitude
// data.coords.longitude
});
}
I don't understand the code ... does it seem to be doing the same thing twice?
It's got the getCurrentPosition and the watchPosition sections and both get the saqme data?
Why? I'm I missing something?
In summery: this.geolocation.getCurrentPosition() is used to retrieve the device's current location once, while this.geolocation.watchPosition() Registers a handler function that will be called automatically each time the position of the device changes, returning the updated location.
References:
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API
Code Examples:
//define the userPositionWatch
userPositionWatch: any;
//Subscriber to the userPositionWatch
this.userPositionWatch = this.geolocation.watchPosition()
.subscribe(
(position: any) => {
// This method will be triggered each time the position of the device changes
console.debug("geolocation.watchPosition => the callback function have been triggered");
let data: any = position;
if (data.coords !== undefined) {
this.doSomethingWithThePos(data.coords.latitude, data.coords.longitude);
} else {
console.error("geolocation.watchPosition() => the callback function have been triggered and the position is undefined", data);
}
}
, (error: any) => {
console.error("geolocation.watchPosition() => the callback function have been triggered and the there is an error:", error);
});
//To remove the subscription
this.userPositionWatch.unsubscribe();
//Another way to remove the subscription
navigator.geolocation.clearWatch(this.userPositionWatch);
this.geolocation.getCurrentPosition()
.then((position: any) => {
let data: any = position;
if (data.coords !== undefined) {
this.doSomethingWithThePos(data.coords.latitude, data.coords.longitude);
} else {
console.error("geolocation.getCurrentPosition() => the position is undefined", data);
}
}).catch(error => {
console.error("geolocation.getCurrentPosition() => the position has error:", error);
})
I hope it was clear...
Related
I am going to use vonage for text service.
However, only node.js syntax exists, and the corresponding API is being used.
There is a phenomenon that the callback is executed later when trying to receive the values returned from the callback to check for an error.
How can I solve this part? The code is below.
await vonage.message.sendSms(from, to, text, async (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
console.log(result);
return result;
When an error occurs as a result of executing the above code,
result{error:undefined}
3
Outputs are in order.
From what I can understand the issue is that you are passing a async callback. you could simply just give vonage.message.sendSms() a synchronous callback like so.
const result = {};
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
if you want to use async or promises I would suggest something like this
const sendSMS = (from, to, text) => new Promise( (resolve, reject) => {
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
reject(err);
} else {
resolve(responseData);
}
});
});
// elsewhere
sendSMS(from, to, text)
.then(...)
.catch(...);
I have a problem getting the result from a Cloud Function.
This is my Cloud Function:
exports.retrieveTrips = functions.https.onCall((data, context) => {
const uidNumber = context.auth.uid;
var arrayOfResults = new Array();
var idOfFoundDoc;
var query = admin.firestore().collection('Users').where('UID','==', uidNumber);
query.get().then(snapshot =>
{
snapshot.forEach(documentSnapshot =>
{
idOfFoundDoc = documentSnapshot.id;
});
var queryDoc = admin.firestore().collection('Users').doc(idOfFoundDoc).collection('Trips');
queryDoc.get().then(snapshot =>
{
snapshot.forEach(documentSnapshot =>
{
arrayOfResults.push(documentSnapshot.data());
});
console.log('ARRAY: ' , arrayOfResults);
return arrayOfResults;
})
.catch (err =>
{
console.log ('Error adding document: ', err);
});
})
.catch (err => {
//response.send('Error getting documents', err);
console.log ('Error getting documents', err);
});
And this is the code that I have in my application.
#IBAction func RetrieveTripsButton(_ sender: Any)
{
self.functions.httpsCallable("retrieveTrips").call() {(result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain
{
let message = error.localizedDescription
print ("Message: " + message)
}
return
}
print ("Result: -> \(type(of: result))")
print("Result.data type: \(type(of: result?.data))");
print ("Result.data -> \(result?.data)")
}
}
And this is the printed result.
Result: -> Optional<FIRHTTPSCallableResult>
Result.data type: Optional<Any>
Result.data -> Optional(<null>)
The console log is able to print arrayOfResults correctly. Furthermore, when I change this functions to onRequest and feed it the relevant information, the res.status(200).send(arrayOfResults) is able to display the array of JSON in the page.
If I placed the return arrayOfResults; outside of the .then function, I would get a result along with an empty array. My issue is similar to this problem here but I'm unable to receive even that when I return { text: "some_data" }; .
Any help would be great, thank you!
You have to chain the different promises and return the result of the promises chain, as follows.
Note that it is actually what the OP explains in his answer to the SO post you mention "The issue was that I forgot to return the actual promise from the cloud function".
exports.retrieveTrips = functions.https.onCall((data, context) => {
const uidNumber = context.auth.uid;
const arrayOfResults = new Array();
let idOfFoundDoc;
const query = admin.firestore().collection('Users').where('UID','==', uidNumber);
return query.get().then(snapshot => { // here add return
snapshot.forEach(documentSnapshot =>
{
idOfFoundDoc = documentSnapshot.id;
});
const queryDoc = admin.firestore().collection('Users').doc(idOfFoundDoc).collection('Trips');
return queryDoc.get(); // here add return and chain with then()
})
.then(snapshot => {
snapshot.forEach(documentSnapshot => {
arrayOfResults.push(documentSnapshot.data());
});
console.log('ARRAY: ' , arrayOfResults);
return { arrayOfResults : arrayOfResults }; //return an object
})
.catch (err => {
console.log ('Error getting documents', err);
//Here you may return an error as per the documentation https://firebase.google.com/docs/functions/callable#handle_errors, i.e. by throwing an instance of functions.https.HttpsError
});
});
I would also suggest that you look at these two videos from the Firebase team, about Cloud Functions and promises: https://www.youtube.com/watch?v=7IkUgCLr5oA and https://www.youtube.com/watch?v=652XeeKNHSk.
I am using Angular 5 and want to return data from function getDionaeaResults in json format after subscribing to service
getDionaeaResults(sql) : any {
this.dionaeaService.getDionaeaConnectionLogs(sql).subscribe(res => {
this.data = res;
}),
(error: any) => {
console.log(error);
});
return this.data;
}
After calling this function, this.totalAttacks prints undefined.
getTotalAttack() {
this.totalAttacks = this.getDionaeaResults("some query")
console.log(this.totalAttacks,'attacks')
}
Would suggest using the Obseravable .map() function.
getDionaeaResults(sql) : Observable<any> {
return this.dionaeaService
.getDionaeaConnectionLogs(sql)
.map(res => res);
}
getTotalAttack(sql){
this.getDionaeaResults("some query")
.subscribe(
res => { this.totalAttacks = res; },
err => { console.log(err); }
);
}
this.getDionaeaResults is returning undefined because the service you're calling is asynchronous you have to wait for the subscribe callback. as Observables are asynchronous calls
this.data=res
might execute after the return statement. You can perhaps call that dionaeaService directly inside getTotalAttack() function, like this:
getTotalAttack(sql){
this.dionaeaService.getDionaeaConnectionLogs(sql).subscribe(res => {
this.totalAttacks = res;
}),
(error: any) => {
console.log(error);
});
}
I'm working with the facebook API and I need to get the profile data to save it in a database. The code returns fine, but when I try to access the data it shows me error because they are null.
This is my code:
this.fb.login(['public_profile', 'user_friends', 'email'])
.then((res: FacebookLoginResponse) => {
token = res.authResponse.accessToken;
userId = res.authResponse.userID;
if (res.status == 'connected') {
this.fb.api('/' + res.authResponse.userID + '?fields=id,first_name,last_name,gender, email,birthday', [],
function onSuccess(result) {
var name = JSON.stringify(result.first_name);
this.register(name);
},
function onError(error) {
console.log(error);
});
} else {
console.log('Not logged in');
}
}).catch(e => console.log('Error logging into Facebook', e));
When I try to call the register method it generates error because the method does not exist, but this is not true. I also tried to save the result of name to a global variable but when it is to be assigned it shows that it can not assign the variable, ie as if the global variable was not defined.
The solution was to change
function onSuccess(result) {
var name = JSON.stringify(result.first_name);
this.register(name);
},
function onError(error) {
console.log(error);
});
for
(result) => {
var name = JSON.stringify(result.first_name);
this.register(name);
},
(error) => {
console.log(error);
});
I am trying to figure out how to always check if the location service is enabled. By always I mean like a real-time checker. What I have now is only in one view. I am checking when the user signs in - if the location service is enabled, he signs in. However, if it's unenabled then an Alert dialog appears:
This is my function that checks if it's enabled:
checkLocation() {
this.diagnostic.isLocationEnabled().then(
(isAvailable) => {
console.log('Is available? ' + isAvailable);
if (isAvailable) {
this.navCtrl.setRoot(UserTypePage);
} else {
alert('Please turn on the location service');
if (this.autoLogin) {
this.autoLogin();
}
}
}).catch((e) => {
console.log(e);
alert(JSON.stringify(e));
});
}
I call this function when a user tries to sign in.
Example with Facebook sign in:
facebookLogin(): void {
this.global = ShareService.getInstance();
this.subscriptions.push(this.authProvider.loginWithFacebook().subscribe((user) => {
this.loading.dismiss().then(() => {
this.global.setUserName(user.displayName);
this.global.setProfilePicture(user.photoURL);
this.global.setUserId(this.authProvider.currentUserId);
this.tokenstore();
this.checkLocation(); //HERE
})
}, error => {
this.loading.dismiss().then(() => {
let alert = this.alertCtrl.create({
message: error.message,
buttons: [
{
text: "Ok",
role: 'cancel'
}
]
});
alert.present();
});
}, (err) => {
console.error("error: " + JSON.stringify(err));
}));
this.loading = this.loadingCtrl.create({
content: 'Signing in...'
});
this.loading.present();
}
I want this function to work in the whole application not just in the login view. How do I do that?
This is a classic scenario where Angular Dependency Injection will help you to reuse an existing method across components/views.
You can create a LocationCommonService in your application and define the method to check if Location service is enabled.
Now inject LocationCommonService in all the components where there is a need to call the required function.