Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
necrotic
Aug 2, 2005
I owe my brother big time for this!
That do/while loop doesn't look like it does anything except set some embedded data to the same value 10 times. If you want the difference between two Dates in days I'd use something like:

code:
// First we get the last Time and now in milliseconds
var lastTime = +new Date("2015-11-17 18:23:45"); // Pretend from ${e://Field/day1date}
var thisTime = +new Date();

// Now we find the difference in milliseconds
var diffTime = thisTime - lastTime;

// Now we calculate how many days that is (0.9 days is still 0 days)
var numberOfDays = Math.floor(diffTime / 1000 / 60 / 60 / 24);
You can make this shorter, but I like the explicitness of each step. The shortest I'd go is embedding the diffTime step into the numberOfDays calculation.

Adbot
ADBOT LOVES YOU

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

necrotic posted:

That do/while loop doesn't look like it does anything except set some embedded data to the same value 10 times. If you want the difference between two Dates in days I'd use something like:

code:
// First we get the last Time and now in milliseconds
var lastTime = +new Date("2015-11-17 18:23:45"); // Pretend from ${e://Field/day1date}
var thisTime = +new Date();

// Now we find the difference in milliseconds
var diffTime = thisTime - lastTime;

// Now we calculate how many days that is (0.9 days is still 0 days)
var numberOfDays = Math.floor(diffTime / 1000 / 60 / 60 / 24);
You can make this shorter, but I like the explicitness of each step. The shortest I'd go is embedding the diffTime step into the numberOfDays calculation.

Thanks for this. The code I have right now is working fine though most of the time, so is there something wrong with it that would cause it to behave inconsistently particularly on mobile devices? I don't want to change the code to something different unless I know it's going to fix my issue.

qntm
Jun 17, 2009

Rosalind posted:

First a few caveats:
  • I am not a Javascript programmer.
  • I am not technically even a programmer at all
  • All the code I write is completely self-taught as I go to solve problems in my workplace so there's probably better ways to do the things I'm doing.
So with those in mind, I work for a research team as their head data person. As part of our research, we collect surveys from participants using Qualtrics. Qualtrics has a neat little feature where you can embed bits of Javascript into a question. We have a study where we need to calculate the difference in days from when they completed their first survey compared to when they are completing their current survey, but the calculation seems to work inconsistently on mobile devices. The code right now looks like this:

code:
Qualtrics.SurveyEngine.addOnload(function()
{
  var surv1date=new Date("${e://Field/day1date}");
      surv1date.setHours(0);
      surv1date.setMinutes(0);
      surv1date.setSeconds(0);
      surv1date.setMilliseconds(0);
  
  var one_day=86400000;
  
  var difference = Math.abs(todayDate.getTime() - surv1date.getTime())/one_day + 1;
  Math.round(difference);
	
var intCount = 1;
var daydiff = null;

	do {	
  //$('daydiff').value = Math.round(difference);
   Qualtrics.SurveyEngine.setEmbeddedData('daydiff', Math.round(difference));
	daydiff = Math.round(difference);
	intCount++;
}
while (intCount <= 10  && (daydiff == undefined || daydiff == null || daydiff == NaN || isNaN(daydiff) == true));
	
	var strday = "on Day ";
	var strfinal = strday.concat(daydiff);
	var newQuestionText = questionText.replace("on Day", strfinal);

	$(this.questionContainer).down('.QuestionText').innerHTML = newQuestionText;

});
;
On mobile devices, it appears sometimes that this code is not running correctly and daydiff is not calculated, but other times it works fine. It will work one day and not the next on the same phone, same browser, same everything. I set it up to loop through the daydiff calculation up to 10 times thinking that might make a difference. We've seen the problem on both iOS and Android devices, but never on a desktop device. Javascript was enabled on these devices. Any ideas?

* Your indentation needs fixing.
* Unnecessary extra semicolon at the very end of the code.
* The line Math.round(difference) all by itself doesn't do anything. You need difference = Math.round(difference).
* Try to avoid having two separate variables daydiff and difference, especially since they seem to do the same thing.
* The test daydiff == NaN can be removed, this will always return false even when daydiff is NaN.
* You can just do var newQuestionText = "on Day " + String(daydiff);.
* Don't use .innerHTML, use .text.

And everything said above.

qntm
Jun 17, 2009

Rosalind posted:

Thanks for this. The code I have right now is working fine though most of the time, so is there something wrong with it that would cause it to behave inconsistently particularly on mobile devices? I don't want to change the code to something different unless I know it's going to fix my issue.

What is populating the field "day1date" which you use for surv1date? Is it a number of Unix milliseconds (a 13-digit number like "1447875934389"), or a string containing a date and time such as "December 17, 1995 03:24:00" or "1995-12-17T03:24:00"? If the latter, what time zone is that date in? Is it the client's local time zone, or is it always UTC?

When JavaScript's Date constructor parses a single string containing the date and time, I believe it assumes that that date and time has been presented in UTC. But if the client's local time isn't UTC, then that means JavaScript will have constructed an incorrect date, leading to issues.

Can you be more specific when you say it doesn't work? What error do you see? Does your code throw exceptions, does it return "NaN", does it return a value which is off by 1 day?

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

qntm posted:

When JavaScript's Date constructor parses a single string containing the date and time, I believe it assumes that that date and time has been presented in UTC. But if the client's local time isn't UTC, then that means JavaScript will have constructed an incorrect date, leading to issues.

This sounds like the bug to me. Why even pass in a string to start with? Just get Date.now(), save that number in your <whatever>, and then compare to another Date.now() when the user completes the process. You are already dividing by a fixed number to get your days, why complicate it so much?

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

qntm posted:

What is populating the field "day1date" which you use for surv1date? Is it a number of Unix milliseconds (a 13-digit number like "1447875934389"), or a string containing a date and time such as "December 17, 1995 03:24:00" or "1995-12-17T03:24:00"? If the latter, what time zone is that date in? Is it the client's local time zone, or is it always UTC?

When JavaScript's Date constructor parses a single string containing the date and time, I believe it assumes that that date and time has been presented in UTC. But if the client's local time isn't UTC, then that means JavaScript will have constructed an incorrect date, leading to issues.

Can you be more specific when you say it doesn't work? What error do you see? Does your code throw exceptions, does it return "NaN", does it return a value which is off by 1 day?

day1day is a string that looks like "Friday, October 30, 2015". There's no time zone since we set all the times = 0 in the javascript, but we're located in EST as are all the people taking the survey.

Unfortunately I've been unable to replicate the problem myself. I get emails when our participants encounter a survey error and what caused it. All I know is that daydiff is not calculating correctly for these people in that it checks to ensure that daydiff is a number. If it were off by a day, it should still work correctly.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Rosalind posted:

day1day is a string that looks like "Friday, October 30, 2015". There's no time zone since we set all the times = 0 in the javascript, but we're located in EST as are all the people taking the survey.

Unfortunately I've been unable to replicate the problem myself. I get emails when our participants encounter a survey error and what caused it. All I know is that daydiff is not calculating correctly for these people in that it checks to ensure that daydiff is a number. If it were off by a day, it should still work correctly.

Setting the hours/minutes/seconds/milliseconds doesn't eliminate the time zone, it just sets the time to 12AM in whatever timezone the host is in.

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

Skandranon posted:

Setting the hours/minutes/seconds/milliseconds doesn't eliminate the time zone, it just sets the time to 12AM in whatever timezone the host is in.

Oh see this is stuff I never deal with as 90% of my work is statistical in nature and stuff like time zones are incredibly annoying to deal with. I am going to try the simplified code recommended by necrotic along with the suggestions from qntm and see if that improves things. I can also just calculate the daydiff later when we download the data for cleaning I suppose, but I liked calculating it in real time so we could tell the participants they were on day X of Y of their daily surveys.

qntm
Jun 17, 2009
Oh hell, it's worse than I thought. I set my time zone to UTC+11 (Australia somewhere). If I get JS to parse a simple date (no time information)

code:
> new Date("1970-01-01")
Thu Jan 01 1970 11:00:00 GMT+1100 (AUS Eastern Daylight Time)
> (new Date("1970-01-01")).getTime()
0
it looks like it assumes that the date was UTC, and selects midnight UTC on that date. (Incidentally, this means that setting the hour, minute and second to 0 is unnecessary.) But if I add an explicit time to that string:

code:
> new Date("1970-01-01 00:00:00").getTime()
-39600000
Suddenly it assumes I'm speaking about local time! In conclusion, Date's magical string-parsing behaviour is a shocker and worth avoiding. My suggested solution is to find whatever code originally populated that field and get the Date object back directly.

Unit tests would also help.

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

Ok so the issue seems to be that the code isn't causing an error or that the day difference is being calculated as null or something weird, their devices aren't running the javascript at all. We dug into our backend data and if the value had been calculated, even incorrectly or as NaN, we'd be able to see it. There's just no value at all for any of these people. I'm going to contact Qualtrics support.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Date's string constructor's parsing isn't even specified to handle the result of Date.prototype.toString, let alone anything else. Never use it.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Yeah, date parsing is strictly the domain of purpose built libraries like 'moment'.

Never never never try to do even moderate amounts of date and time stuff in JavaScript without a library. You will gently caress it up, guaranteed.

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.
Not to mention the ECMAScript standard up to ES6 specifically instructs browser developers to handle dates incorrectly.

quote:

The implementation of ECMAScript should not try to determine whether the exact time was subject to daylight saving time, but just whether daylight saving time would have been in effect if the current daylight saving time algorithm had been used at the time. This avoids complications such as taking into account the years that the locale observed daylight saving time year round.

If the host environment provides functionality for determining daylight saving time, the implementation of ECMAScript is free to map the year in question to an equivalent year (same leap-year-ness and same starting week day for the year) for which the host environment provides daylight saving time information. The only restriction is that all equivalent years should produce the same result.

qntm
Jun 17, 2009
God made UTC, the rest is the work of man.

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.

qntm posted:

God made UTC, the rest is the work of man.
Did you know that to synchronize clocks between earth-based receivers and GPS satellites, the code needs to account for relativistic time dilation outside of Earth's gravity?

mmkay
Oct 21, 2010

Vulture Culture posted:

Did you know that to synchronize clocks between earth-based receivers and GPS satellites, the code needs to account for relativistic time dilation outside of Earth's gravity?

And the dilation due to velocity (though not as much).

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

qntm posted:

God made UTC, the rest is the work of man.

If God wanted us to have time zones, he would have something something something.... *goes back to bed*

Kuule hain nussivan
Nov 27, 2008

I'm sure this is a question with a really simple answer I'm just not getting. I'm trying to create a to-do list using angular, where each item has a checkbox that can be used to mark it as done.

I'm using angular to generate the tasks from a list using ng-repeat, and the template for the checkbox is <input type="checkbox" class="check">. I've been trying to implement a button that marks all the tasks as done, but haven't had any luck. I've been trying different variations of

code:
$scope.markAll = function() {
        var tasks = document.getElementsByClassName("check");
        for (var task in tasks) {
            task.click()
        }
 };
like task.checked = true, etc. Any ideas?

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

I'm sure this is a question with a really simple answer I'm just not getting. I'm trying to create a to-do list using angular, where each item has a checkbox that can be used to mark it as done.

I'm using angular to generate the tasks from a list using ng-repeat, and the template for the checkbox is <input type="checkbox" class="check">. I've been trying to implement a button that marks all the tasks as done, but haven't had any luck. I've been trying different variations of

code:
$scope.markAll = function() {
        var tasks = document.getElementsByClassName("check");
        for (var task in tasks) {
            task.click()
        }
 };
like task.checked = true, etc. Any ideas?

You are thinking of this backwards. You don't need to do things like "getElementsByClassName". The whole point of Angular is to get away from that. You should have a backing collection of items, that is your list that you are ng-repeating over. Your markAll function should simply go over that list and set the "checked" (or whatever) boolean to true.

code:
$scope.markAll = function() {
        for (var task in $scope.listThatNGRepeatUses) {
            task.booleanCheckboxesAreBoundTo = ! task.booleanCheckboxesAreBoundTo;
        }
 };
If you want it to make them all checked/unchecked, you can modify appropriately, the one above will toggle each checkbox back and forth.

Skandranon fucked around with this message at 17:56 on Nov 22, 2015

Kuule hain nussivan
Nov 27, 2008

Skandranon posted:

You are thinking of this backwards. You don't need to do things like "getElementsByClassName". The whole point of Angular is to get away from that. You should have a backing collection of items, that is your list that you are ng-repeating over. Your markAll function should simply go over that list and set the "checked" (or whatever) boolean to true.

code:
$scope.markAll = function() {
        for (var task in $scope.listThatNGRepeatUses) {
            task.booleanCheckboxesAreBoundTo = ! task.booleanCheckboxesAreBoundTo;
        }
 };
That was actually my original plan. I gave the tasks a done variable and had markAll work with that. I just couldn't figure out how to bind the checkbox elements to the boolean variable within the task object.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

That was actually my original plan. I gave the tasks a done variable and had markAll work with that. I just couldn't figure out how to bind the checkbox elements to the boolean variable within the task object.

code:
<input ng-repeat="task in listThatNGRepeatUses" type="checkbox" ng-model="task.booleanCheckboxesAreBoundTo"></input>

Kuule hain nussivan
Nov 27, 2008

Skandranon posted:

code:
<input ng-repeat="task in listThatNGRepeatUses" type="checkbox" ng-model="task.booleanCheckboxesAreBoundTo"></input>

Nope, still can't get it to work :(

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Kuule hain nussivan posted:

Nope, still can't get it to work :(

IE or Chrome?

If .checked = true doesn't work in Chrome, then you might be running into this: http://stackoverflow.com/questions/16950751/checked-checked-not-working-in-chrome.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

Nope, still can't get it to work :(

Can you be more specific about what isn't working? Beyond posting the basic "using checkboxes with Angular" code, it becomes really hard to speculate further on what could possibly be going wrong with your code without more information.

Kuule hain nussivan
Nov 27, 2008

Skandranon posted:

Can you be more specific about what isn't working? Beyond posting the basic "using checkboxes with Angular" code, it becomes really hard to speculate further on what could possibly be going wrong with your code without more information.
I actually got it to work. The problem seemed to be that the for each loop I had set up to go through $scope.tasks wasn't working properly. Each task variable just wound up being just the number of the current index, rather than the object at said index, so the object values never got changed. Changed it to a for (i; i < x; i++) loop, and everything works fine. Coming from Java, I really dislike how a var can be goddamn anything in Javascript.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

I actually got it to work. The problem seemed to be that the for each loop I had set up to go through $scope.tasks wasn't working properly. Each task variable just wound up being just the number of the current index, rather than the object at said index, so the object values never got changed. Changed it to a for (i; i < x; i++) loop, and everything works fine. Coming from Java, I really dislike how a var can be goddamn anything in Javascript.

Aargh, yeah, I should have seen it... I miss that a lot because I primarily use TypeScript, which supports the ES6 for...of, which DOES work as you and I thought for...in would.

In short, you should convert to using TypeScript.

Odette
Mar 19, 2011

Here's my lovely npm package, how can I improve it? Any glaring errors or bad implementations of ... anything?

It's quite simple, but I'm hoping that I can use the feedback as a learning opportunity on what NOT to do, etc.

MrMoo
Sep 14, 2000

Odette posted:

Here's my lovely npm package, how can I improve it? Any glaring errors or bad implementations of ... anything?


That looks like a custom license? Stick with one of the standard OSI ones. I found the MIT license reference in the package file.

The function names getStory() and getInfo() are not technically accurate but at least they are short.

MrMoo fucked around with this message at 16:27 on Nov 25, 2015

Kuule hain nussivan
Nov 27, 2008

Sigh, more problems which I have no idea how to fix.

I have an Angular app which uses a Firebase service. The folder structure is

/app.js
/contollers/controller.js
/services/firebase_service.js

And in the HTML these are loaded in the order app, service, controller.

I'm trying to inject the firebase service into the controller, but it keeps giving me an "Unknown provider: $firebaseArrayProvider <- $firebaseArray <- FirebaseService" error.

My code is..

code:
app.js:

var App = angular.module('App', ['firebase']);

firebase_service.js:

App.service('FirebaseService', function ($firebaseArray) {
});

controller.js:
App.controller('Controller', function($scope, FirebaseService){
});
I've also tried using App.controller('Controller', ['$scope', 'FirebaseService', function($scope, FirebaseService) {}]); but that doesn't help at all. Any clues or advice about what I'm doing wrong?

fantastic in plastic
Jun 15, 2007

The Socialist Workers Party's newspaper proved to be a tough sell to downtown businessmen.
The error looks like it's trying to find $firebaseArray to inject into your FirebaseService and not finding it. What's $firebaseArray?

Kuule hain nussivan
Nov 27, 2008

Tao Jones posted:

The error looks like it's trying to find $firebaseArray to inject into your FirebaseService and not finding it. What's $firebaseArray?
It's one of the services offered by Firebase. It works fine if I don't try to inject it into the controller, so I don't think it's an issue with FirebaseService not finding it.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

It's one of the services offered by Firebase. It works fine if I don't try to inject it into the controller, so I don't think it's an issue with FirebaseService not finding it.

Firebase being some sort of Angular Module, which you've specified to load in your module with the name 'firebase'? When do you load firebase.js?

Kuule hain nussivan
Nov 27, 2008

Skandranon posted:

Firebase being some sort of Angular Module, which you've specified to load in your module with the name 'firebase'? When do you load firebase.js?
That's loaded in the HTML, right after the main angular app.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

That's loaded in the HTML, right after the main angular app.

There is your problem, it has to load before it. Should be treated like a library, that your app depends upon.

Kuule hain nussivan
Nov 27, 2008

Skandranon posted:

There is your problem, it has to load before it. Should be treated like a library, that your app depends upon.
No go. If I change the load order to firebase -> angularfire -> angular, I get a complaint that angular is missing, but firebase -> angular -> angularfire gives the same error.

Edit: Apparently it was a version problem. Updating everything helped. Still only getting empty data, but at least it's not an error.

Kuule hain nussivan fucked around with this message at 19:31 on Nov 26, 2015

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Kuule hain nussivan posted:

No go. If I change the load order to firebase -> angularfire -> angular, I get a complaint that angular is missing, but firebase -> angular -> angularfire gives the same error.

Edit: Apparently it was a version problem. Updating everything helped. Still only getting empty data, but at least it's not an error.

Ok, when you said "Angular app" you meant angular.js. That has to load before other modules, as all the other Angular modules need to call angular.module("",[]) just like you do.

Something you are not doing that you should is specifying your DI as strings, as you mentioned earlier. Do this always, it's the proper way, examples that don't do this just haven't been updated.. This will allow minification to take place properly. Secondly, now that you aren't getting an injection error, you probably either aren't using Firebase correctly in some way. The Firebase API example has a step that either you are missing or simply ommited in your post

code:
var app = angular.module("sampleApp", ["firebase"]);
app.controller("SampleCtrl", function($scope, $firebaseArray) {
  var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/messages");
  $scope.messages = $firebaseArray(ref); // need to call $firebaseArray with the Firebase object to get stuff
});

Lord Windy
Mar 26, 2010
I've never been good at Web development. I don't understand it at all. I went to live in the world of low level C instead. For shits and giggles I went with a group of friends to a Hackathon and we've walked away with something that both might win and we think might be a good startup idea to pursue over the summer break.

I really need to get good at javascript to be much help. I stress the part of really good, because some of the libraries we have used are cryptic as gently caress. We are using Riot.js, Ventus.js and heaps of other things in some mashup. I want to be able to detangle this mess before it becomes a headache.

So do you guys have any resources to help bring people up to speed on all this?

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Lord Windy posted:

I've never been good at Web development. I don't understand it at all. I went to live in the world of low level C instead. For shits and giggles I went with a group of friends to a Hackathon and we've walked away with something that both might win and we think might be a good startup idea to pursue over the summer break.

I really need to get good at javascript to be much help. I stress the part of really good, because some of the libraries we have used are cryptic as gently caress. We are using Riot.js, Ventus.js and heaps of other things in some mashup. I want to be able to detangle this mess before it becomes a headache.

So do you guys have any resources to help bring people up to speed on all this?

As a general rule, the "let's pull random javascript libraries that do cool things and smash them together" style of JS development is just a pain to work with. I would say:

a) Minimize the library use in your project. If you don't really need the whole library, or can do it yourself, just cut it. Vanilla JS is almost always easier to deal with than library slop.
b) Consider converting to a compile-to-JS language like typescript. Raw JS is more difficult to maintain than compile to JS languages.
c) Minimize the amount of stuff done in the browser - web apis are easier to test and maintain, and it'll be easier to refactor when someone decides to get rid of your flavor of the month UI library.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
For me the first step to "getting" Javascript, was when I realized that Javascript has function scope. Any var you declare is visible everywhere in the function. Or at least it helped me not make as many mistakes.

The second step probably was realizing that it has first class functions. And what first class functions are :blush:

My hints are:
Use strict mode and JSHint right from the start.

Adbot
ADBOT LOVES YOU

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL

Wheany posted:

My hints are:
Use strict mode and JSHint eslint right from the start.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply