Checking User location every 5 minutes javascript - javascript

So I think this solution will work but just wanted to see if there was something a bit more elegant. So I want to allow a user to "check in" to a location and once they have done so I want to see if they have remained in that location. I would check about every 5 minutes. Once they have checked out then I could stop checking. The goal is to get the total time spent at a store. I am using the Javascript SDK for Parse. This is the basic jist of my solution not a complete solution. Using a while loop to check a users location and to continue to do so as long as they remained checked in. Thanks for any suggestion and help! (Also I am using Google maps api to get store location). Just to be sure I am asking more if my approach is correct not if my code is correct.
checkIn: function(){
store_location = "something predefined";
Parse.GeoPoint.current({
success: function(point){
var user_location = new google.maps.LatLng(point.latitude,point.longitude);
if(user_location = store_location){
this.checkedIn();
},
}
});
},
checkedIn: function(){
///run loop while the user is still checked in
///increment total time by 5 min every time loop is called
var checked_in = true;
total_time = 0;
while(checked_in){
setTimeout(function(){
var user_location = new google.maps.LatLng(point.latitude,point.longitude);
if(user_location = store_location){
total_time=total_time + 5
}else{
checked_in = false;
}
}, 3000000)
}
}

window.setInterval(function(){
var user_location = new google.maps.LatLng(point.latitude,point.longitude);
if(user_location = store_location){
total_time=total_time + 5
}else{
checked_in = false;
}
},3000000);

instead of using the while and setTimeout, why dont you use setInterval? i think it is easier and simplify the code

Related

Creating a for loop that loops over and over =

So I have a weird problem (as I can do this using dummy code, but cannot make it work in my actual code) -
The concept is simple - I need a for loop that upon hitting its max "I" number reverts "I" to 0 again and creates a loop over and over -
DUMMY CODE:
for(i=0;i<10;i++){
console.log(i);
if(i === 10){
i = 0
}
}
Now for the longer code (sorry)
function reviewF(){
// add ID to each of the objects
reviews.forEach((e, i)=>{
e.id = i
})
// get the elements to be populated on page
var name = document.querySelector('p.name');
var date = document.querySelector('p.date');
var rating = document.querySelector('.rating_stars');
var review = document.querySelector('p.review_content_text');
// reverse the array - so the newest reviews are shown first (this is due to how the reviews where downloaded)
var reviewBack = reviews.slice(0).reverse();
// start the loop - go over each array - take its details and apply it to the elements
/**
* THIS IS WHAT I WOULD LIKE TO LOOP OVER FOREVER
*
* **/
for (let i = 0; i < reviewBack.length; i++) {
(function(index) {
setTimeout(function() {
// document.getElementById('reviews').classList.remove('slideOut')
name.classList.remove('slideOut')
date.classList.remove('slideOut')
rating.classList.remove('slideOut')
review.classList.remove('slideOut')
name.classList.add('slideIn')
date.classList.add('slideIn')
rating.classList.add('slideIn')
review.classList.add('slideIn')
name.innerHTML = reviewBack[i].aditional_info_name;
date.innerHTML = reviewBack[i].Date;
rating.innerHTML = '';
review.innerHTML = reviewBack[i].aditional_info_short_testimonial;
if(reviewBack[i].aditional_info_short_testimonial === 'none'){
reviewBack.innerHTML='';
}
var numberOfStars = reviewBack[i].aditional_info_rating;
for(i=0;i<numberOfStars;i++){
var star = document.createElement('p');
star.className="stars";
rating.appendChild(star);
}
setTimeout(function(){
// document.getElementById('reviews').classList.add('slideOut')
name.classList.add('slideOut')
date.classList.add('slideOut')
rating.classList.add('slideOut')
review.classList.add('slideOut')
},9600)
}, i * 10000)
})(i);
// should create a infinite loop
}
console.log('Loop A')
}
// both functions are running as they should but the time out function for the delay of the transition is not?
reviewF();
EDITS >>>>>>>>
Ok so I have found a hack and slash way to fix the issue - but its not dry code and not good code but it works.....
this might make the desiered effect easier to understand
reviewF(); // <<< this is the init function
// this init2 function for the reviews waits until the reviews have run then
// calls it again
setTimeout(function(){
reviewF();
}, reviews.length*1000)
// this version of the innit doubles the number of reviews and calls it after that amount of time
setTimeout(function(){
reviewF();
}, (reviews.length*2)*1000)
From trying a bunch of different methods to solve this issue something I noticed was when I placed a console.log('Finished') at the end of the function and called it twice in a row (trying to stack the functions running..... yes I know a horrid and blunt way to try and solve the issue but I had gotten to that point) - it called by console.log's while the function was still running (i.e. the set time out section had not finished) - could this have something to do with it.
My apologies for the rough code.
Any help here would be really great as my own attempts to solve this have fallen short and I believe I might have missed something in how the code runs?
Warm regards,
W
Why not simply nest this for loop inside a do/while?
var looping = True
do {
for(i=0;i<10;i++){
console.log(i);
}
if (someEndCondition) {
looping = False;
}
}
while (looping);
I would think that resetting your loop would be as simple as setting "i = 0" like in the dummy code. So try putting the following into your code at the end of the for loop:
if(i === 10){
i = 0;
}

Why won't one part of my javascript function run even though it is syntactically correct?

I'm a programming newbie trying to make a function that asks for a password, but will display an error message if the password attempt is wrong more than five times. I have tried fiddling around with those code a bunch of different ways and it just won't work. I have a variable called count that starts as 0, and each time a wrong password is entered, 1 is supposed to be added to count, and once count is greater than 5, the error message is supposed to be displayed.
document.getElementById("word-checker").onclick = function () {
var count = 0;
var inputValue = document.getElementById("text-input").value;
var secretWord = "password123";
if (count > 5) {
alert("You have had 5 unsuccessful login attempts. You account has been temporarily locked.");
} else if (inputValue == secretWord) {
alert("Your answer is correct!");
document.getElementById("text-input").value = "";
} else if (inputValue!==secretWord) {
count++;
alert("Your answer is incorrect. Please try again.");
document.getElementById("text-input").value = "";
}
}
This is driving me insane. I'm sure it's a simple beginner's mistake though. Any input that would help me understand why this won't work would be met with a lot of gratitude.
You are resetting count to 0 every time the click event is triggered:
document.getElementById("word-checker").onclick = function () {
var count = 0; // <-- button clicked, set the value to zero.
// ...
}
This means that count will never get to 5 (in fact, it never gets to be > 1 either, as when count++ increments the value to 1, it is set back to 0 on the next click). Consequently, the if (count > 5) part of the if statement will never be triggered.
You need to declare count outside of the click event:
var count = 0;
document.getElementById("word-checker").onclick = function () {
// use count here
// ...
}
you are redefining count as 0 every time on the click event. You need to define count as a global outside the function and then ++ on every error.
Also, try to correct your indentation as it helps reading.

Destroying scopes/isolated scopes? Angularjs

This code is a little wild but I am more concerned about concepts here than definite code responses. I am working on a combat system for a game. I have npc characters running on an "attack" loop. Once the player has reduced an npc bad guy's hit points to zero, I want to remove that entity from the map/DOM/scope etc. ...some code (the code in question will be towards the end) -
Loading the npc character data from database..an array, all same properties, but different values. $scope.encounters gets ng-repeated in the HTML and builds out the characters on the screen. That data is then send to $scope.encounter_a() function to do more stuff.
db.getNpcCombat(npc_combat_set).success(function(data){
$scope.encounters = [];
$scope.encounters = data;
angular.forEach(data, function(value, key){
console.log(value);
$scope.encounter_a(value);
});
This sets a timer for a progress bar with different rates for different npcs, once the time hits 100, cancels timer and then runs the attack function...which was looped through, so it is running with different times for each npc according to their data. So value is the data from one npc entity.
$scope.encounter_a = function(value){
value.attack_count = 0;
$timeout(function(){
var set_timer = $interval(function() {
value.attack_count += 1;
if(value.attack_count >= 100){
$interval.cancel(set_timer);
$scope.attack(value);
}
}, value.attack_rate);
}, 500);
}
This part looks a little crazy but does it's job. This is still receiving the data of one npc entity. Each enemy has different attacks, so basically, this is getting that certain NPC's attacks data from the database, then randomizing which attack will get used, it then calculates whether or not the attack will hit the player character. Whether or not the attack hits or misses, it will loop back to encounter_a().
$scope.attack = function(data){
$timeout(function(){
db.getNpcFeats(data.feats).success(function(feat_data){
//randomize which feat is used ...get amount of feats
var count = feat_data.length;
//randomize number
count = getRandomInt(1, count);
count = count - 1;
//get feat_hit success - gets random number between 1-10
feat_success = getRandomInt(1, 10);
$('#enemy_'+data.id+' ul li .attack_text h5').html(feat_data[count].feat_name + '!');
$('.attack_text').removeClass('fadeOut').addClass('fadeIn');
$timeout(function(){
$('.attack_text').removeClass('fadeIn').addClass('fadeOut');
}, 1000);
if(feat_data[count].feat_chance >= feat_success){
$scope.damage_amount= getRandomInt(parseInt(feat_data[count].feat_min_damage), parseInt(feat_data[count].feat_max_damage));
$scope.$watch('damage_amount', function() {
$('.feat_name').html(feat_data[count].feat_name);
$('.feat_damage').html('Damage - ' +$scope.damage_amount);
$('.feat_hit .text-danger').html("You've been hit!!");
$('.outer-container').addClass('tada');
$('.feat_hit').removeClass('fadeOutDown').addClass('fadeInUp');
$scope.player_hp = $scope.player_hp - $scope.damage_amount;
if($scope.player_hp >= 0){
//future player death function
}
$timeout(function(){
$('.feat_hit').removeClass('fadeInUp').addClass('fadeOutDown');
}, 2000);
});
}
});
$scope.encounter_a(data);
}, data.attack_delay);
}
Finally, here is the code that is giving me trouble. This code is essentially disconnected from the above code. This is the attack code for the player attacking the NPCs. Which has worked, except for when the NPC's hitpoints reach zero, not sure what to do.
$scope.playerFeatAttack = function(player_feat){
//if player has not selected npc to attack, show message and prevent attack then remove message else allow attack
if (!$('.enemy_container').hasClass('attack_selected')){
$('.helper_dialog_area').removeClass('lightSpeedOut');
$('.helper_dialog_area').removeClass('hide');
$('.helper_dialog_area h4').html('CLICK AN ENEMY TO ATTACK!!!');
$('.helper_dialog_area').addClass('lightSpeedIn');
$timeout(function() {
$('.helper_dialog_area').removeClass('lightSpeedIn');
$('.helper_dialog_area').addClass('lightSpeedOut');
}, 2500);
}else{
//calculate hit damage
var hit_damage = getRandomInt(parseInt(player_feat.feat_min_damage), parseInt(player_feat.feat_max_damage));
//calculate attack success
var attack_success_roll = getRandomInt(1, 10);
//if attack passes, run attack
if(player_feat.feat_chance >= attack_success_roll){
//determine which NPC to attack based on the .attack_selected class
//not sure if this is a good way but this is how getting the specific NPC hitpoints
var elem = angular.element($(".attack_selected .npc_hp")).scope();
$scope.npc_hp = $('.attack_selected .npc_hp').html();
//watch for changes in the hitpoints
$scope.$watch('npc_hp', function(){
//change the hitpoints on the screen using jquery..probably not ideal way
var npc_hp = parseInt($scope.npc_hp) - parseInt(hit_damage);
$('.attack_selected .npc_hp').html(npc_hp);
var hp_after_attack = $('.attack_selected .npc_hp').html();
This main code in question -
if(hp_after_attack <= 0){
$('.attack_selected').addClass('flipOutX');
var what = angular.element($('.attack_selected')).scope();
}
});
}
}
}
This last part is the code in question. If the NPC's hitpoints go below 0, first planning to add a CSS class to do an animation, then want to remove that character from the game. If I console log this -
var what = angular.element($('.attack_selected')).scope();
Which is the element I want to remove, I can see the encounter object in the main scope which is that NPC entities data. I tried to change that to NULL, figuring it would eliminate the entity's data, hence not being able to do anything. Also just tried removing the element from the DOM, which of course, removes it from the screen, but then it keeps running attacks.
In $parent of the scope, I can see the $scope.attack() function..I changed that to NULL, but then that stops all of the NPCs from attack.
What I need to do is kill the attack() function for the specific NPC...but when I console $scope, it looks to me like there is only 1 attack function in the scope, not seperate ones for each "encounter" entity/npc.
Is there some way I can code the attack() function to be attack to the main scope of each of these elements? Maybe an isolated scope (which I don't really understand what it is)?
This is my learning AngularJS project...so any advice on a better way to accomplish the above and also to eliminate the NPC from the battle after it's be killed would be really great. Let me know if you need any more info from me.

split window location accordingly

I am trying to redirect the user according to a lang choice drop down and using their current window.location
So if the user is visiting
xxxx.com will need to go to xxxx.com/langchoice.
2.xxxx.com/currentlang/test.php will need to go to xxxx.com/langchoice/test.php
3 xxxx.com/test.php will need to go to xxxx.com/langchoice/test.php
I have done 1 and 2 but not particularly happy with the way that I coded this considering that if more languages might come I need to add a line every time...can this be rewritten better?
var s = window.location.href;
if (s.indexOf(".php") !=-1)
{
if (s.indexOf("/en/") !=-1)
{
var location=window.location.href.replace("/en/","/"+evt.selectedItem+"/");
}
else if (s.indexOf("/gr/") !=-1)
{
var location=window.location.href.replace("/gr/","/"+evt.selectedItem+"/");
}
else if (s.indexOf("/it/") !=-1)
{
var location=window.location.href.replace("/it/","/"+evt.selectedItem+"/");
}
else
{
}
window.location.replace(location);
}
else
{
var location=window.location.href.replace("#","");
window.location.replace(location+evt.selectedItem);
}
This does make the check to see if there is a "language", but the basic idea to replace would be
There are many ways of doing it, this is one way
var orgPathName = window.location.pathname;
var newPathName = orgPathName.replace(/^\/[^\/]*/,"/" + evt.selectedItem);
var newUrl = window.location.href.replace(orgPathName, newPathName);
Now to do the detection, you do a simple test
var hasLang = (/^\/(en|gr|in)\//i).test(window.location.pathname);
pain with this is maintaining the language list
How do you persist langchoice? Do you store it in a cookie?
I think you are essentially saying that the user should be at:
xxxx.com/[langchoice]etc
at all times.
So you could split on '/' and then, if it exists, check item [1]. If it matches the langchoice cookie, continue, if it doesn't, swap it out.

Random Items and linking

Sorry if the post was unclear, I’ll try to explain as best I can. I’m creating a social psychology experiment online, and I need a function to be able to select at random different names (like John, Mike, Alex etc.). While looking for help online I found this code:
function swapImages(){
var $active = $('#myGallery .active');
var $next = ($('#myGallery .active').next().length > 0) ? $('#myGallery.active').next() : $('#myGallery img:first');
$active.fadeOut(function(){
$active.removeClass('active');
$next.fadeIn().addClass('active');
});})
Using this code and the "mousetrap" library I was able to change the name when a key is pressed. But I have no clue on how I can make the names appear randomly (this means, not in the order they are on the code, but different every time I do it). And after 40 different names, I need to link to another html page.
Thanks for the help, and sorry if my last post was confusing.... This is my first approach to programing :)
Old post:
Im quite new to the programing world, i need some help making this code select random items, not in the order I put them on. Also, i got this from the web and i need it to stop after 40 items and link to antoher page.
Thanks for the help
If you simple need to select random names - selection from array using Math.Random is the simplest approach:
var names = ["John", "Mike", "Peter", "Sid", "Homer"]
var idx;
do {
idx = parseInt(names.length * Math.random());
alert(names[idx]);
names.splice(idx, 1);
} while (names.length > 0)
Basically it generates random index within boundaries of array's length, selects element at that index and then removes the element from array. Loop exits when there're no more elements to display.
Demo: http://jsfiddle.net/4NNTA/1/
If your list has over 40 items and you need to exit after 40 - add a counter and condition to the while. After exiting the loop you can redirect to another page by setting location.href to URL of page you want to go to.
UPDATE This is a function that used revised code above. It lets you specify arbitrary number of names:
var Names = function () {
var data;
var counter;
function initData() {
data = ["John", "Mike", "Peter", "Sid", "Homer"]
}
this.init = function (c) {
counter = c;
initData()
}
this.getName = function () {
if (counter === 0) {
return ""
} else {
if (data.length === 0) initData();
var idx = parseInt(data.length * Math.random());
var sName = data[idx]
data.splice(idx, 1);
counter--;
return sName
}
}
}
Inside of function initData you can specify array of names. Then you initialize it by passing number of names you want to display (this example initializes it to 40):
var myNames = new Names();
myNames.init(40);
And then every time you call
myNames.getName()
It will give you next random name. The names will not repeat until data is exhausted - then the array is reinitialized and random un-repeated names begin again. When all 40 names are retrieved - function returns empty string, which you can check and act accordingly.

Categories