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!
Also, don't use eval. You can access properties on an object using brackets: console.log(classroom.room1.students[student2].grade + 5);

Adbot
ADBOT LOVES YOU

5pitf1re
Oct 4, 2014

space ninja in space
I'd also like to point out that your object structure is rather bad and technically wrong, especially if you consider semantics.

This one looks a lot better:

code:
var classroom = {
    room1: {
        students: [
            {
                name: "Jim",
                isHomeworkComplete: false,
                grade: 50
            },
            {
                name: "Tim",
                isHomeworkComplete: true,
                grade: 100
            }
        ]
    }
};
Although I don't quite understand why your classroom would be divided in classrooms.

5pitf1re fucked around with this message at 14:50 on Jan 2, 2015

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Lumpy posted:

Phone posting so not much detail for you but you want to use a "for in" loop, coupled with hasOWnProperty.

And if you don't want to deal with any of that poo poo, consider using the lodash or underscore libraries and then using _.each().

ufarn
May 30, 2009
I have a form that outputs a formatted version of the input in plain HTML with basic jQuery, but as it's meant for sharing, the ideal would be to generate an image file. How would that work for a static website?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

ufarn posted:

I have a form that outputs a formatted version of the input in plain HTML with basic jQuery, but as it's meant for sharing, the ideal would be to generate an image file. How would that work for a static website?

You have a text input that gets rendered as formatted html?

You want to output an image with words on it?

That is a server side thing, not a Javascript thing. You need to use some image output library for your server framework.

(Or if you like how your html output looks like in the browser, I guess you could use PhantomJS to render the html into an image and serve that)

ufarn
May 30, 2009

Wheany posted:

You have a text input that gets rendered as formatted html?

You want to output an image with words on it?

That is a server side thing, not a Javascript thing. You need to use some image output library for your server framework.

(Or if you like how your html output looks like in the browser, I guess you could use PhantomJS to render the html into an image and serve that)
I take it that would involve rasterize.js, but does that require the rendering to be on its own page, or can you fetch the specific DOM element generated by jQuery to render?

Pollyanna
Mar 5, 2005

Milk's on them.


Can someone tell me why the hell this fiddle doesn't work? Everything seems to be created just fine, but something goes horribly wrong during rendering and I can't tell what's getting broken. I just get a grey square for my Map.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

ufarn posted:

I take it that would involve rasterize.js, but does that require the rendering to be on its own page, or can you fetch the specific DOM element generated by jQuery to render?

PhantomJS is a "real web browser". I guess you could render document fragments or something to bitmap, but I have only made screenshots of a whole page the few times I've used it.

So you could just direct PhantomJS to yourdomain.com/funny_text.php?phrase=butts, have the server return the page just like it would to any other browser, then save the screenshot from phantomjs and serve it as a static image.

You can definitely use jQuery to remove unwanted elements from the page before rendering the screenshot.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Pollyanna posted:

Can someone tell me why the hell this fiddle doesn't work? Everything seems to be created just fine, but something goes horribly wrong during rendering and I can't tell what's getting broken. I just get a grey square for my Map.

Gray square = you have not set your zoom level and center point.

https://www.youtube.com/watch?v=21PDd17dnnI

Pollyanna
Mar 5, 2005

Milk's on them.


Wheany posted:

Gray square = you have not set your zoom level and center point.

https://www.youtube.com/watch?v=21PDd17dnnI

It's always some brainless mistake like that. :cripes: Thanks, I should watch some more of these videos.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

I feel like I'm not getting something about ES6 Promises.

Say I want to get something from an url and do some transformations on it.

JavaScript code:
function aThingGetter() {
  return Promise($.get("http://blahblah"))
      .then(function (results) {
        return doSomethingWithResults(results)
      })
      .then(function (results) {
        return doSomethingElse(results)
      })
      .then(function (results) {
        return somethingElse(results)
      })
}

function wrongDoStuffWithAThing() {
  var aThing = aThingGetter();
  console.log(aThing);              // Nope!  A thing is never available outside of a promise.
} 

function rightDoStuffWithAThing() {
  aThingGetter().then(function (aThing) {
    console.log(aThing)             // You've got to wrap it in a `then` function.
  })
}
So, basically I think you can't ever get a value "out" of a promise? Is that right?

I'm just thinking about how once you return a promise, you've always got to append a .then(function (result) {blahblahblah}) to use that value and its turtles all the way down.

Fish Ladder Theory
Jun 7, 2005

Thermopyle posted:

I feel like I'm not getting something about ES6 Promises.

first of all $.get returns a jquery promise so there's no reason to wrap it in a native promise that i can see.

you always must use .then (and catch) to get the result of a promise because promises are asynchronous. you can no more do what you're attempting in wrongDoStuff with promises than you can with callback-using code. the action of the promise (fetching json) hasn't even begun to occur when your console.log statement executes

Fish Ladder Theory fucked around with this message at 05:07 on Jan 6, 2015

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Fish Ladder Theory posted:

first of all $.get returns a jquery promise so there's no reason to wrap it in a native promise that i can see.

JQuery promises are broke and JQuery won't fix them because of backwards compatibility.

You can cast them to es6 promises like I do above.

I'm on phone, so you can google about how they're broken.

As for the rest...yeah, I guess I'll just get used to it. I probably should've used a better example. Where I get frustrated with them is when I'm using them as more error control than async-enabling.

Fish Ladder Theory
Jun 7, 2005

i'm not sure i've ever seen promises used when async control isn't needed-- but you might look at a real full-featured promise library (the es6 one is very limited right now) like Q or Bluebird for a lot more control methods. Q, for example, has Promise.inspect() which lets you get the status (resolved/rejected) and respective value/reason of a promise synchronously.

The native Promise has valueOf() in Chrome, which appears to do the same thing, but it doesn't actually appear to be documented anywhere, and I actually can't figure out how to use it like .inspect()

code:
var a = new Promise(function(resolve, reject) { resolve(5)})
a.valueOf()
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 5}

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You're probably going to have a bad time if you decide to inspect a promise to see if it's already resolved or whatever and then do something based on that.

You can't just block or spin while waiting for it to happen. So you have to write the "the promise hasn't been resolved yet, so set it up to do the right thing when that happens" code. After doing that, you might as well just stop - writing extra code to do the same thing in a different way if the promise has been resolved already is just a bunch of effort (and potential for hard-to-find bugs if they're subtly different) for literally zero benefit.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Thermopyle posted:

I'm just thinking about how once you return a promise, you've always got to append a .then(function (result) {blahblahblah}) to use that value and its turtles all the way down.

Yes, that's sort of the point. A Promise represents some value in the future. There's no value currently, only a value in the future.

Note that if the promise is already resolved it will call your callback with the value immediately, so there's no chance to "miss" the value gone by. That might be your misunderstanding.

Kobayashi
Aug 13, 2004

by Nyc_Tattoo
Speaking of promises, it seems like all the error handling of a promise chain collapses down to a single catch(). For example, if I want to 1) start up a database and then 2) call some API if and only if the DB is ready, I'm not sure how to chain those together such that the first promise can reject in a DB-specific way and the second promise rejects in an API-specific way.

As far as I can tell, I can either create some complicated, catch-all error handler, create two separate promises that fire independently, or I can nest the second promise inside the first, leading to the same "rightward drift" that I'd get with callbacks. Am I missing some other option? Does that make any sense?

Fish Ladder Theory
Jun 7, 2005

Kobayashi posted:

Speaking of promises, it seems like all the error handling of a promise chain collapses down to a single catch(). For example, if I want to 1) start up a database and then 2) call some API if and only if the DB is ready, I'm not sure how to chain those together such that the first promise can reject in a DB-specific way and the second promise rejects in an API-specific way.

As far as I can tell, I can either create some complicated, catch-all error handler, create two separate promises that fire independently, or I can nest the second promise inside the first, leading to the same "rightward drift" that I'd get with callbacks. Am I missing some other option? Does that make any sense?

You can parse the reject reason in your handler. If you're using Bluebird you can chain multiple catches to catch different error types (including custom Error types). you can also use Promise.all() and check the result of each promise individually and handle errors then.

code:
somePromise.then(function() {
    return a.b.c.d();
}).catch(TypeError, function(e) {
    //If a is defined, will end up here because
    //it is a type error to reference property of undefined
}).catch(ReferenceError, function(e) {
    //Will end up here if a wasn't defined at all
}).catch(function(e) {
    //Generic catch-the rest, error wasn't TypeError nor
    //ReferenceError
});
There are probably others and I'd love to hear what people are doing, since promise error handling always annoys me a little.

RobertKerans
Aug 25, 2006

There is a heppy lend
Fur, fur aw-a-a-ay.

Promise.resolve first, then chain. If you've got your initial chunk of stuff you then want to run through a series of transforms, you want a value not wrapped in a promise object. You could use a helper to simplify (sorry, phone posting off the top of my head, so this is a bit primitive, just arity 1 and no error handling)

code:

function chain(seed, ...transforms) {
  return transforms.reduce(prev, current) {
    return prev.then(current);
  }, Promise.resolve(seed));
}

// chain(data, transform, transform, transform)

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Suspicious Dish posted:

Yes, that's sort of the point. A Promise represents some value in the future. There's no value currently, only a value in the future.

Note that if the promise is already resolved it will call your callback with the value immediately, so there's no chance to "miss" the value gone by. That might be your misunderstanding.

Oh. Yeah.

The funny thing is that I knew this. I just hadn't completely figured out what I was uncomfortable about and hooked up my uncomfort with the fact that promises will callback immediately.

Thanks.

RobertKerans posted:

Promise.resolve first, then chain.

Huh. That's cool

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
So here's something I've struggled with for awhile. The whole "Global variables = death" mantra has been successfully drilled into me.

Where I'm at a loss is understanding the best way to access input if I can't store it globally.

I made a calculator that does a large part of my job, taking into account the many conflicting state, local and federal laws that we have to juggle when reviewing programs. The calculator takes pasted user input, parses it into a usable form and stores it in an array for use further down the line in the calculations.

http://jsfiddle.net/fgccLa81/

HTML code:
<input type="text" id="paste" placeholder="Paste Things Inside of Me" />
code:
function gatherpaste(){
   var pasted = $('#paste').val().split(' ');
    return pasted;
}

function doCalculations(){
    var getArray = gatherpaste();
    var newArray = [];
    for(var x=0; x<getArray.length; x++){
        if(getArray[x] < 1750){
            newArray.push(getArray[x]);
        }
        else{
            getArray[x] = "Illegal";
        }
    }
}

function doDifferentCalculations(){
    var getArray = gatherpaste();
    //etc etc
}

There's dozens of different functions that need to refer back to the array generated from gatherpaste() to perform their own discrete calculations. It seems so incredibly inefficient and wrong to have each function call gatherpaste(), querying the dom each time. But outside of declaring a global variable, i.e.

code:
 var globalGatherPaste = gatherpaste();
I don't know how else to do it?

Sedro
Dec 31, 2008
It's as simple as wrapping your code in a function and immediately invoking it:
JavaScript code:
(function() {

var paste = gatherpaste();

... your code ...

}());

// paste is not accessible out here

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic

Sedro posted:

It's as simple as wrapping your code in a function and immediately invoking it:
JavaScript code:
(function() {

var paste = gatherpaste();

... your code ...

}());

// paste is not accessible out here

Wouldn't this just be invoked right away, before the user has a chance to paste into the input field?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Having each function call gatherpaste() is definitely wrong, since you're still using global state in some deeply-nested obscure part of your code.

The correct way to do this is to pass your array of data as a parameter to each function. Or better yet, instead of passing an array of raw data, create an object with meaningful field names that holds the same information and pass that around.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Raskolnikov2089 posted:

So here's something I've struggled with for awhile. The whole "Global variables = death" mantra has been successfully drilled into me.

Where I'm at a loss is understanding the best way to access input if I can't store it globally.

I made a calculator that does a large part of my job, taking into account the many conflicting state, local and federal laws that we have to juggle when reviewing programs. The calculator takes pasted user input, parses it into a usable form and stores it in an array for use further down the line in the calculations.

http://jsfiddle.net/fgccLa81/

HTML code:
<input type="text" id="paste" placeholder="Paste Things Inside of Me" />
code:
function gatherpaste(){
   var pasted = $('#paste').val().split(' ');
    return pasted;
}

function doCalculations(){
    var getArray = gatherpaste();
    var newArray = [];
    for(var x=0; x<getArray.length; x++){
        if(getArray[x] < 1750){
            newArray.push(getArray[x]);
        }
        else{
            getArray[x] = "Illegal";
        }
    }
}

function doDifferentCalculations(){
    var getArray = gatherpaste();
    //etc etc
}

There's dozens of different functions that need to refer back to the array generated from gatherpaste() to perform their own discrete calculations. It seems so incredibly inefficient and wrong to have each function call gatherpaste(), querying the dom each time. But outside of declaring a global variable, i.e.

code:
 var globalGatherPaste = gatherpaste();
I don't know how else to do it?

Where are these functions called? When the user pushes a button? If so then gatherpaste() there and pass the result to each DoCalc function as a parameter.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic

HappyHippo posted:

Where are these functions called? When the user pushes a button? If so then gatherpaste() there and pass the result to each DoCalc function as a parameter.

Forgot that part. Yeah it's a button, since there are a couple of fields the user has to set that determines which calculation are run.

So basically I would...

code:
<button onclick="doitall()"></button>
code:
function doitall(){
    var paste = gatherpaste();
    doCalc(paste);
    doCalc2(paste);
   printResults(doCalc, doCalc2);
}

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Structure your functions so that you can call it independently of the user's input, and return values instead of manipulating global state.

Let's say you're trying to debug something, and you're not sure what's going on. You can simply pop open the Developer Console and type:

JavaScript code:
docalc([1, 2, 3, 4, 5]);
And make sure that the results are like you expect. Later, when you're more advanced, you can verify the behavior automatically using something called "unit tests", so that whenever you make a change, you can be sure that the functions behave like you expect.

no_funeral
Jul 4, 2004

why
I'm trying to detect when a user has entered an @ symbol, within a contenteditable div, for the purpose of doing mentions. Is this possible using only keyup? I was using keypress, but this didn't allow me to check whether they had just hit enter, or backspace, etc.

The way I'm doing it is keeping a last key, and second to last key buffer. if last key was @, and second to last was whitespace, I'd allow them to mention. This is incredibly bad, though, and messes up in lots of scenarios. If its possible just using keyup, as opposed to having to gently caress around with keypress, I'd love to do it that way.

Kobayashi
Aug 13, 2004

by Nyc_Tattoo
^ I recently bookmarked keymaster.js, a dependency-free library for keyboard shortcuts. I figure that's probably easier than figuring out all the various idiosyncrasies across platforms and browsers.

no_funeral
Jul 4, 2004

why

Kobayashi posted:

^ I recently bookmarked keymaster.js, a dependency-free library for keyboard shortcuts. I figure that's probably easier than figuring out all the various idiosyncrasies across platforms and browsers.

thanks, this is working.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

I'm looking for a nice javascript logging library/framework.

The two things I'm most looking for:

1. Easily enable/disable console logging for dev/production.
2. The nicest thing would be something that integrates with some cloud logging solution like loggly/papertrail/whatever that will let me log selected events from clients.

Any recommendations here?

edit: BTW, I'm just using logentries javascript client now. Just wondering if anyone has any experience with something they like more.

Thermopyle fucked around with this message at 22:29 on Jan 8, 2015

MrMoo
Sep 14, 2000

That seems a little problematic on scalability, you can capture standard console logging in Chrome or Firefox under Linux in its parent console. The biggest problem I found recently is that logging objects, e.g. console.log ("log this:", object) keeps a reference on the object until the log is wiped from memory! Incredibly dangerous implementation for long running pages.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

MrMoo posted:

That seems a little problematic on scalability, you can capture standard console logging in Chrome or Firefox under Linux in its parent console. The biggest problem I found recently is that logging objects, e.g. console.log ("log this:", object) keeps a reference on the object until the log is wiped from memory! Incredibly dangerous implementation for long running pages.

Yeah, I'll just be using it while my app is out to a limited number of testers.

5pitf1re
Oct 4, 2014

space ninja in space

Thermopyle posted:

I'm looking for a nice javascript logging library/framework.

The two things I'm most looking for:

1. Easily enable/disable console logging for dev/production.
2. The nicest thing would be something that integrates with some cloud logging solution like loggly/papertrail/whatever that will let me log selected events from clients.

Any recommendations here?

edit: BTW, I'm just using logentries javascript client now. Just wondering if anyone has any experience with something they like more.

Sounds like you're looking for dbg

no_funeral
Jul 4, 2004

why

Sitting Bull posted:

I'm trying to detect when a user has entered an @ symbol, within a contenteditable div, for the purpose of doing mentions. Is this possible using only keyup? I was using keypress, but this didn't allow me to check whether they had just hit enter, or backspace, etc.

The way I'm doing it is keeping a last key, and second to last key buffer. if last key was @, and second to last was whitespace, I'd allow them to mention. This is incredibly bad, though, and messes up in lots of scenarios. If its possible just using keyup, as opposed to having to gently caress around with keypress, I'd love to do it that way.

I have another question WRT to this:

What is an intelligent way of determining whether or not the user has entered @ to mention somebody, after hitting backspace. Short of keeping track of the character to the left of the caret, which I don't know how to do this, since the user is entering text into a contenteditable div, not an input. The contenteditable div may have many paragraphs, containing other paragraphs, or spans.

down with slavery
Dec 23, 2013
STOP QUOTING MY POSTS SO PEOPLE THAT AREN'T IDIOTS DON'T HAVE TO READ MY FUCKING TERRIBLE OPINIONS THANKS

Sitting Bull posted:

I have another question WRT to this:

What is an intelligent way of determining whether or not the user has entered @ to mention somebody, after hitting backspace. Short of keeping track of the character to the left of the caret, which I don't know how to do this, since the user is entering text into a contenteditable div, not an input. The contenteditable div may have many paragraphs, containing other paragraphs, or spans.

https://code.google.com/p/rangy/

edit. I guess https://github.com/timdown/rangy is the current URL now

down with slavery fucked around with this message at 20:47 on Jan 9, 2015

no_funeral
Jul 4, 2004

why

thank you pengy

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Fish Ladder Theory posted:

The native Promise has valueOf() in Chrome, which appears to do the same thing, but it doesn't actually appear to be documented anywhere, and I actually can't figure out how to use it like .inspect()

code:

var a = new Promise(function(resolve, reject) { resolve(5)})
a.valueOf()
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 5}

All objects have .valueOf.

PleasureKevin
Jan 2, 2011

i'm doing this learnyounode exercise: https://github.com/rvagg/learnyounode/blob/master/exercises/juggling_async/problem.md

they recommend using the async library, but their example solution doesn't use it. what function would i probably use to do what it's asking?

EDIT: async.map works

PleasureKevin fucked around with this message at 02:00 on Jan 11, 2015

Adbot
ADBOT LOVES YOU

Analytic Engine
May 18, 2009

not the analytical engine
We use Angular at work and I'm stumped on synchronizing some JS. I have a function that should run after a specific Angular html partial is finished loading, but jQuery's loading functions require URLs of entire html pages.

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