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
streetlamp
May 7, 2007

Danny likes his party hat
He does not like his banana hat
messing with setting up a JSON file with some data that gets used across a bunch of sites but each site would only need the parts that are relevant to it. I figured I would just check if each object had a certain keyword and if so grab that object.

So the more relevant question for this thread would be, is indexOf really the best way to do this? I assumed something that just spits out a boolean response would be available but all I dug up was this. Second question if anyone knows, is this JSON structure alright for what I'm trying to do?


JSON:
code:
{
    "being": [
        {
            "id": "1",
            "projects": ["red", "blue"],
            "firstName": "John",
            "lastName": "Butts",
            "title": "CEO",
            "bio": "I'm a terrible person",
            "photo": "butt.jpg"
        },
        {
            "id": "2",
            "projects": ["red"],
            "firstName": "Barack",
            "lastName": "Obama",
            "title": "President",
            "bio": "lol im obama",
            "photo": "obama.png"
        }
    ]
}

JS:

code:

    $.ajax({
        type: "GET",
        url: 'beings.json',
        dataType: 'json',
    }).success( function(response){
        $.each(response.being, function(){
            var arr = this.projects;
            var index = arr.indexOf("blue");

            if (index >= 0) {
              //return only people who worked on project blue
            }
        });
    });

Adbot
ADBOT LOVES YOU

My Rhythmic Crotch
Jan 13, 2011

You could also do something like this
code:
var people = [];
$.each(response.being, function() {
	if($.inArray("blue",this.projects) != -1) {
		people.push(this)
	}
});

My Rhythmic Crotch fucked around with this message at 01:04 on Oct 3, 2014

Fish Ladder Theory
Jun 7, 2005

streetlamp posted:

messing with setting up a JSON file with some data that gets used across a bunch of sites but each site would only need the parts that are relevant to it. I figured I would just check if each object had a certain keyword and if so grab that object.

So the more relevant question for this thread would be, is indexOf really the best way to do this? I assumed something that just spits out a boolean response would be available but all I dug up was this. Second question if anyone knows, is this JSON structure alright for what I'm trying to do?



use filter:

code:
relevant = response.beings.filter(function(el) {
  return el.projects.indexOf("blue") >= 0
});

Fish Ladder Theory fucked around with this message at 17:59 on Oct 4, 2014

Analytic Engine
May 18, 2009

not the analytical engine
edit: wrong thread

Analytic Engine fucked around with this message at 04:30 on Oct 6, 2014

streetlamp
May 7, 2007

Danny likes his party hat
He does not like his banana hat

Fish Ladder Theory posted:

use filter:

code:
relevant = response.beings.filter(function(el) {
  return el.projects.indexOf("blue") >= 0
});


Nice, going to try this today

Drythe
Aug 26, 2012


 
I (the client) want(s) to have a pop-up jquery box to confirm the submission of a page. What's the cleanest way to execute a modal confirmation and then fire off the server side event? I haven't done much of executing server side code from javascript. This is being done on .net and c#.

My Rhythmic Crotch
Jan 13, 2011

$.ajax

necrotic
Aug 2, 2005
I owe my brother big time for this!

Well, to get a modal you'd want to use the built-in confirm or one of the many modal libraries (bootstrap, foundation, jquery UI's dialog). Then use $.ajax when they confirm the save.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

necrotic posted:

Well, to get a modal you'd want to use the built-in confirm or one of the many modal libraries (bootstrap, foundation, jquery UI's dialog). Then use $.ajax when they confirm the save.

Don't use alert() or confirm() for anything, just use some UI kit's dialogs.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Wheany posted:

Don't use alert() or confirm() for anything, just use some UI kit's dialogs.

Which is why I mentioned them. `confirm` works fine for quick mockups and mucking about, though.

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER
What are some good books to get caught up to speed on Javascript and, eventually, Node.js? I had Javascript and JQuery by Jon Duckett and Node.js in Action by Mike Cantelon et al recommended to me and just wanted to see if there were better ones out there.

Most of my experience is with C++ and Java, and I've never really played with any web languages or technologies outside of a little bit of PHP. My goal is to pickup Node.js in a month or less. Crazy?

My Rhythmic Crotch
Jan 13, 2011

Crazy indeed. Why would you want to learn node.js at all? :v:

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER

My Rhythmic Crotch posted:

Crazy indeed. Why would you want to learn node.js at all? :v:

Another bar regular would be able to pass on my resume with a strong recommendation, if I can give him something that he can really sink his teeth into. Node.js is a big part of their tech stack. :v:

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL

BirdOfPlay posted:

What are some good books to get caught up to speed on Javascript and, eventually, Node.js? I had Javascript and JQuery by Jon Duckett and Node.js in Action by Mike Cantelon et al recommended to me and just wanted to see if there were better ones out there.

Most of my experience is with C++ and Java, and I've never really played with any web languages or technologies outside of a little bit of PHP. My goal is to pickup Node.js in a month or less. Crazy?

Eloquent Javascript (http://eloquentjavascript.net/) is pretty good in my opinion. If you want to dig deeper into Node after that, http://nodeschool.io/ has a lot of tutorials and exercises.

minidracula
Dec 22, 2007

boo woo boo
Some time ago I saw links to and some pages about at least one (or more) JS UI libraries/frameworks that implemented a classical kind of nodes and wires graph GUI, similar to the interfaces of Max/MSP, Reaktor, Bidule, or Blueprints in Unreal Engine 4. Does anyone know what I'm talking about, and have links? Searching with the keywords I recall hasn't found me what I'm looking for so far.

Thanks in advance.

My Rhythmic Crotch
Jan 13, 2011

You might try something like this, which depends on D3.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Are you thinking of PlumbJS?

I'm using it at work combined with AngularJS under the hood to make a node-based workflow system, which is a basic ripoff of UE4 Blueprint. I posed about it over in the Data Visualisation Thread the other week. It's been really robust so far, and works on IE8, apparently (not tested).

The documentation is more like a brain dump than a real guide, but once you get to grips with it, it's pretty straight forward.

There's a couple of half-assed implementations of AngularJs and PlumbJS together, which are handy reference:

My Rhythmic Crotch
Jan 13, 2011

I want some very simple tooling for javascript. All I want to do is:
- Adjust some variables depending on the deployment. For example, I might have API_ROOT defined differently if I am developing on my computer vs running on the production server.
- Auto-minify the main application code.
- Bundle all dependencies into one file.

None of this is rocket science and could be done with bash or python... which I might end up doing if the tooling is too much of a PITA. What are your experiences?

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Use gulp, gulp-concat, gulp-uglify, and then maybe you could stick on the start your config variables as a global object? Depends on how you want to do it, but gulp's my preferred for front end building and tooling.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
Anyone know if chrome apps auto-update? I'm using developer dashboard, but the documentation isn't 100% clear as to whether I need to give people a link to update to the latest version or if chrome will just update the installed app itself.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
As far as in aware Chrome extensions do, provided they don't expand their permission scope. I imagine its the same thing. It used to be that you could provide an update URL for checking this, but now its Web Store only its handled by that automatically.

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Vague question with bad code written from memory incoming!

I am having trouble getting my head around setting up some dependent AJAX calls, I had this working with one call using a nested callback but I now need to add a second call and doing it by creating another nested callback seems even worse. Basically, I have two drop down lists that need to be populated with values from an object returned from an AJAX call, but the options in the drop downs are themselves dependent on attributes of the object so I need to do something like:

code:
1 -> AJAX call to get the object
	2.1 -> Based on objectvalue1 make ajax call to get dropdowncontent1
	2.2 -> Based on objectvalue2 make ajax call to get dropdowncontent2
3 -> set values of dropdowns 1 and 2 based on object attributes.
Predictably, sometimes 2.2 doesn't complete by the time 3 runs so it gets all hosed up.

I've taken a look at using promises but these all seem to rely on using a raw ajax call, but I have wrapped my calls into functions so the whole .done thing doesn't seem to work and everything just fires off in whatever order.

What I have is something like this:
code:

function ajaxPOST (url, data,callback){
//wrapper around the jquery ajax function that POSTS data to the specified URL and runs the function callback on success

}

//get an array of values for a dropdown, some of which will be dependent on some other value i.e. changing one dropdown can affect the available values in another
function GetDropDownValues (dropdownid,dropdowntype,dependentvalue)

	var url = ".\endpoint\GetDropdownValues"

	var data ={
	dropdowntype,
	dependentvalue
	};
	
	function callback(result){
		SetDropDownContent (result,dropdownid)
	}

ajaxPOST(url,data,callback);

}

function SetDropDownContent (values,dropdownid){
	//populate #dropdownid with an array of ids and text values
	}

//do ajax call to get the main object - returns "object"
	var object = ObjectCall()
//get the content for the two drop downs based on the content of the object
	GetDropDownValues ("dropdown1","type1",object.objectvalue1);
	GetDropDownValues ("dropdown2","type2",object.objectvalue2);
	
//now set the values of the drop downs to the values in the object	
	PopulateMainObject (Object)
	
But I think because I've wrapped the ajax call into another function I can't just use .done to trigger the next one, or at least it doesn't work when I try it. I'd prefer to keep the ajax functions abstracted away like this as they're used throughout the application but I'm sure I'm missing something obvious.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
ajaxPOST sounds redundant, it sounds like you could just replace that with a direct $.post(url, {data: data, success: callback}), or $.post(url, {data: data}).then(function(){})

Anyway, if you can replace them with a post call, you can use jQuery.when() to wait for multiple promises, example from http://api.jquery.com/jquery.when/#entry-examples

JavaScript code:
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
  // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
  // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
  var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
  if ( /Whip It/.test( data ) ) {
    alert( "We got what we came for!" );
  }
});
So maybe you can do this:
JavaScript code:
var object = ObjectCall();

$.when(
	$.post("endpoint/GetDropdownValues", {data: {gimmeDataFor: 'dropdown1'}}),
	$.post("endpoint/GetDropdownValues", {data: {gimmeDataFor: 'dropdown2'}})
).done(function (v1, v2) {
	populateDropdownsWithData(v1, v2);
}).fail(function (why) {
	console.error('something went wrong because of ' + why)
}).always(function () {
	console.log('cleanup');
})

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
Just checking to see if I working with Javascript by best principals.

I have page with a number of jQuery tooltips on it. I'm assigning the tooltips inside my onReady function:

JavaScript code:
$( function() {
  $('.glyphicon[title]').tooltip();
});
This works fine. However, I have these elements that I later add to the page using ajax. The onReady function is already dead and buried, so I need to call "$('.glyphicon[title]').tooltip();" again in the ajax code. Again, this works fine, but I've got the same code in two places, so that worries me a bit. Is there a better way to assign these tooltips?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

MasterSlowPoke posted:

Just checking to see if I working with Javascript by best principals.

I have page with a number of jQuery tooltips on it. I'm assigning the tooltips inside my onReady function:

JavaScript code:
$( function() {
  $('.glyphicon[title]').tooltip();
});
This works fine. However, I have these elements that I later add to the page using ajax. The onReady function is already dead and buried, so I need to call "$('.glyphicon[title]').tooltip();" again in the ajax code. Again, this works fine, but I've got the same code in two places, so that worries me a bit. Is there a better way to assign these tooltips?

Having 1 case of duplicated code is generally not considered terrible. Bu I guess you could just wrap that in a function: function addTooltip() {$('.glyphicon[title]').tooltip();}, and then just call that function from both places.

That way in the future if your glyphicon selector changes, you only have to change it in that function.

But it's not a huge deal.

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Wheany posted:

ajaxPOST sounds redundant, it sounds like you could just replace that with a direct $.post(url, {data: data, success: callback}), or $.post(url, {data: data}).then(function(){})

Anyway, if you can replace them with a post call, you can use jQuery.when() to wait for multiple promises, example from http://api.jquery.com/jquery.when/#entry-examples

JavaScript code:
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
  // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
  // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
  var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
  if ( /Whip It/.test( data ) ) {
    alert( "We got what we came for!" );
  }
});
So maybe you can do this:
JavaScript code:
var object = ObjectCall();

$.when(
	$.post("endpoint/GetDropdownValues", {data: {gimmeDataFor: 'dropdown1'}}),
	$.post("endpoint/GetDropdownValues", {data: {gimmeDataFor: 'dropdown2'}})
).done(function (v1, v2) {
	populateDropdownsWithData(v1, v2);
}).fail(function (why) {
	console.error('something went wrong because of ' + why)
}).always(function () {
	console.log('cleanup');
})

Yeah I think you might be right - I've just wrapped something that's already wrapped and shot myself in the foot at the same time. I'll give this a go tomorrow when I'm back at work!

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Powerful Two-Hander posted:

Yeah I think you might be right - I've just wrapped something that's already wrapped and shot myself in the foot at the same time. I'll give this a go tomorrow when I'm back at work!

Trip report: I am an idiot, I forgot to actually return the jqXHR object from the ajax call so it could be used outside the wrapper!

Doing that then allows the $.when(dicks).done(butts) approach to work. I've kept the wrapper as is because a) I can't be bothered to refactor existing code and b) it allows me to build some defaults into it that I'd otherwise have to copy and paste everywhere, notably a forcing off of response caching by default because IE10 will cache everything by default which can lead to unusual results.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
code:
"use strict";

function foo(){
    return "bar";
}

function fooTest(){
    var foo = foo();
    console.log(foo);
}

I'm trying to figure out hoisting and am confused here. Why does it matter if my local variable foo in fooTest() has the same name as the function it is being assigned to?

Fish Ladder Theory
Jun 7, 2005

You're declaring a variable foo in your local scope that's shadowing the global function foo(). The declaration of foo in fooTest happens before anything else, because variable declarations (but not assignment) are hoisted to the top of their scope. It looks like this:

code:
function fooTest(){
    var foo; // foo is undefined
    foo = foo();
    console.log(foo);
}
edit: run this, then comment out the "var foo = foo()" and run it again:

code:
function foo(){
    return "bar";
}

function fooTest(){
    
    console.log(foo);
    var foo = foo();
}

Fish Ladder Theory fucked around with this message at 18:15 on Oct 30, 2014

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic

Fish Ladder Theory posted:

You're declaring a variable foo in your local scope that's shadowing the global function foo(). The declaration of foo in fooTest happens before anything else, because variable declarations (but not assignment) are hoisted to the top of their scope. It looks like this:

code:
function fooTest(){
    var foo; // foo is undefined
    foo = foo();
    console.log(foo);
}
edit: run this, then comment out the "var foo = foo()" and run it again:

code:
function foo(){
    return "bar";
}

function fooTest(){
    
    console.log(foo);
    var foo = foo();
}

That makes a lot of sense. I understand now why the console.log before the variable declaration returns undefined. What I'm still stuck on is the debugger "TypeError: undefined is not a function" I'm getting from var foo = foo()

code:
var foot = foo()
That works perfectly, because I'm using a unique variable name. So what is Javascript doing when I'm assigning local variable foo to the global function foo()? By assigning it, aren't I defining it, albeit solely within fooTest()?

To my understanding, what is happening is this:

code:

function fooTest(){
	var foo; //foo declaration hoisted to top
	var foo = foo();  //now already declared variable is being assigned to global function. still a local variable                        
	console.log(foo);  //console.log(foo) is the equivalent of console.log(foo())
}

Clearly this is not what is happening, but why that is, I can't tell.

Raskolnikov2089 fucked around with this message at 18:56 on Oct 30, 2014

Fish Ladder Theory
Jun 7, 2005

When you type var foo = foo(), you are declaring a local variable foo, which immediately shadows the function with the same name (foo), making the global foo function inaccessible from fooTest's scope (because the declaration is hoisted). Your local reference to the global function foo is lost, because your local foo now points to undefined.

Because the function foo is inaccessible, you're trying to call an undefined like it was a function.

It's like you're doing this

var foo = undefined;
foo() // typeerror-- undefined is not a function

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
code:
function fooTest(){
    var foo = foo();
    console.log(foo);
}
Waitttttt. When I type in the foo() in the above, is Javascript just looking for the first foo it finds, in this case our hoisted, undefined foo?

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
Exactly.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
I need to write this example over and over 100 times. In my mind, I couldn't figure out why JavaScript wasn't pointing to the global foo(), but I didn't fully grasp how local variables can take precedence over global ones.

Thank you. A lot more of this beautiful language makes sense now.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Raskolnikov2089 posted:

I need to write this example over and over 100 times. In my mind, I couldn't figure out why JavaScript wasn't pointing to the global foo(), but I didn't fully grasp how local variables can take precedence over global ones.

Thank you. A lot more of this beautiful language makes sense now.

Scope is one of the most important things to grasp in Javascript. This StackOverflow post has a terse but good overview of variable scoping in JS.

Tomed2000
Jun 24, 2002

This might be a dumb question but why do JavaScript libraries use IIFEs if they simply modify the global object in the end anyway? For example this guy says to declare the library in an IIFE then says window.Q = Q. Why not just declare a function named Q which returns the new library object when called? In both cases you are creating new scopes and in both cases you are only adding one function to the global scope. What am I missing here?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Tomed2000 posted:

This might be a dumb question but why do JavaScript libraries use IIFEs if they simply modify the global object in the end anyway? For example this guy says to declare the library in an IIFE then says window.Q = Q. Why not just declare a function named Q which returns the new library object when called? In both cases you are creating new scopes and in both cases you are only adding one function to the global scope. What am I missing here?

Can you give an example of your proposed alternative? You might find it tricky to do it some other way without either making the code less straightforward or polluting the global scope with various other definitions that are really just internal to your library.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Tomed2000 posted:

This might be a dumb question but why do JavaScript libraries use IIFEs if they simply modify the global object in the end anyway? For example this guy says to declare the library in an IIFE then says window.Q = Q. Why not just declare a function named Q which returns the new library object when called? In both cases you are creating new scopes and in both cases you are only adding one function to the global scope. What am I missing here?

Two reasons why IIFE is important here:

  • The Library object (and subsequently Q.fn) is created one time; creating it all inside of Q would rebuild it every call (which could get expensive).
  • Exposing Q.fn (which is also Library.prototype) allows you to create plugins on top of the library. If you were to create a new Library for every call to Q it would require any plugin authors to wrap Q with their own function that would apply the plugin and return it.

Tomed2000
Jun 24, 2002

Jabor posted:

Can you give an example of your proposed alternative? You might find it tricky to do it some other way without either making the code less straightforward or polluting the global scope with various other definitions that are really just internal to your library.

Basically something like this: http://pastebin.com/ryWsAZjg. Just like in the author's example, "T" is the only thing polluting the global scope (unless I'm mistaken) and the library works as expected.

necrotic posted:

Two reasons why IIFE is important here:

  • The Library object (and subsequently Q.fn) is created one time; creating it all inside of Q would rebuild it every call (which could get expensive).
  • Exposing Q.fn (which is also Library.prototype) allows you to create plugins on top of the library. If you were to create a new Library for every call to Q it would require any plugin authors to wrap Q with their own function that would apply the plugin and return it.

Thanks, the first point is definitely something obvious that I was missing! I haven't wrapped my head around the idea of creating plugins but it makes intuitive sense. Another thing I noticed in looking at other examples is that it seems easier to integrate your library with CommonJS and AMD if you use an IIFE instead of just having a function declaration in the global scope.

Adbot
ADBOT LOVES YOU

CuddleChunks
Sep 18, 2004

I'd love some help with learning how to pull data from a remote JSON API into my silly little page.

I want to show the manufacturer info for a given MAC address. The site that gives that info has info about their AP here: http://www.macvendorlookup.com/mac-address-api I've bashed my head against this for a while and am not making any headway.

I'm at http://domain.com/myscript.htm and want my page to grab all the nifty vendor stuff via JSONP. Sometimes I get no response but the Chrome debugger shows I've received *something* back. Other times I get endless X-Site script rejection errors. Here's some code that doesn't work:

code:
<!DOCTYPE html>
<html>
<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
  <title>A JSONP example</title>
</head>
<body>
  <div id="test">default.</div>
<script>
$(document).ready(function () {
	var url = "http://www.macvendorlookup.com/api/v2/";
	url += "00026f123456";
	url += "?callback=?";
    $.getJSON(url, null, function( data ) {
        document.getElementById('test').innerHTML = data.contents;
    });
});
</script>
</body>
</html>
Nothing happens in the Chrome debugger so I guess it's probably failing silently. At least it's not a syntax error that it's spitting out this time. :v:

Thanks for any help you can give. I've read through loads of pages on how to do this and the test code to pull images from Flickr and the like all work. I just can't get my example to work properly.

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