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
Strong Sauce
Jul 2, 2003

You know I am not really your father.





https://twitter.com/etiene_d/status/745218992319639552

A Chrome-only bug tied to let. Pretty funny.

Adbot
ADBOT LOVES YOU

Kekekela
Oct 28, 2004
Optimizer related I guess?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.




lol let is dumb anyway

ulmont
Sep 15, 2010

IF I EVER MISS VOTING IN AN ELECTION (EVEN AMERICAN IDOL) ,OR HAVE UNPAID PARKING TICKETS, PLEASE TAKE AWAY MY FRANCHISE

Kekekela posted:

Optimizer related I guess?

Yes.

https://www.reddit.com/r/javascript/comments/4oxtgk/javascript_developers_be_warned_about_this_crazy/
https://bugs.chromium.org/p/chromium/issues/detail?id=604033
https://github.com/v8/v8/commit/7dfb5beeec8821521beeb2b8eac36707a663064c

Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy
I couldn't figure out how to phrase this for Google so maybe ya'll can help me out.

In the React.js pattern of passing a "callback" as props from parents to their children, how do you retain access to both the parent AND child scope inside the callback? Or rather, is there an elegant way to do it?

Example:

code:
class App extends Component {
	render() {
		return (
			<div className="container">
				<Button callback={this.handleButtonClick} />
			</div>
		);
	}
	handleButtonClick(e) {
		// I want to have my cake and eat it too
	}
}

class Button extends Component {
	render() {
		return (
			<div>
				<button className="btn btn-default" onClick={this.props.callback}>Click me</button>
			</div>
		);
	}
}
I want to have access to App's scope and Button's scope inside of handleButtonClick, mainly so that I can compare props and then do something like change App state.

The most straightforward solution that I've arrived at is to simply pass the parent itself to the child as a prop, but that feels bad in a way I can't really articulate and results in lovely looking code.

Depressing Box
Jun 27, 2010

Half-price sideshow.
If you need to deal with data at the Button level that can't somehow be derived at the App level, you could have a internal event handler in Button that calls the callback:

code:
class App extends Component {
  render() {
    return (
      <div className="container">
        <Button onClick={this.handleButtonClick} />
      </div>
    );
  }
  handleButtonClick(e, internalButtonData) {
    // I want to have my cake and eat it too
  }
}

class Button extends Component {
  handleClick(e) {
    const internalButtonData = 'foobar';
    this.props.onClick(e, internalButtonData);
  }

  render() {
    return (
      <div>
        <button className="btn btn-default" onClick={this.handleClick.bind(this)}>
          Click me
        </button>
      </div>
    );
  }
}
Do you have an example of the type of data you want to compare? It may help you get more specific advice.

Depressing Box fucked around with this message at 21:03 on Jun 23, 2016

Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy
The problem with your solution is that I need access to App's setState method, which I can't do if I bind the scope to Button, and the internalButtonData that I want to send to the callback is Button's internal state. Here's a more detailed and specific picture of what I'm trying to do:

code:
class List extends Component {
	// this.state.entries holds an arbitrary array of <Entry /> components, each with a unique key and handleMove passed as a prop
	// e.g. <Entry key={someUniqueKey} handleMove={this.handleMove} />
	render() {
		return (
			<div>
				{this.state.entries}
			</div>
		);
	}
	handleMove(e) {
		// Here's where I want to compare the <Entry /> to be moved against this.state.entries.
		// Then I can move it as needed in the array and use setState to reorder the list.
		// Pretend there's some logic in here to determine whether it needs to move up or down in the list (maybe from e.target).
	}
}

class Entry extends Component {
	render() {
		return (
			<div>
				<h1>I am an Entry inside of a List, hear me roar!</h1>
				<button className="Move Entry Up" onClick={this.props.handleMove}>Move Entry Up</button>
				<button className="Move Entry Down" onClick={this.props.handleMove}>Move Entry Down</button>
			<div>
		);
	}
}
So basically just a list of arbitrary entries that can be re-ordered. My actual Entry class has complicated internal state and controls and stuff so it doesn't make sense to reduce it into List somehow.

As I mentioned I've already "solved" the problem by passing List to each Entry but There's Got To Be a Better Way!

Depressing Box
Jun 27, 2010

Half-price sideshow.
I solved a similar problem with something along these lines:

code:
class List extends Component {
    // <Entry
    //     key={someUniqueKey}
    //     id={someUniqueKey}
    //     onMove={this.handleMove.bind(this)}
    // />
    render() {
        return (
            <div>
                {this.state.entries}
            </div>
        );
    }

    handleMove(entryId, up) {
        // Get the entry by its id, then move it up or down
        // if the `up` argument is true or false.
    }
}

class Entry extends Component {
    constructor() {
        this.moveUp = this.moveUp.bind(this);
        this.moveDown = this.moveDown.bind(this);
    }

    moveUp(e) {
        e.preventDefault();
        this.props.onMove(this.props.id, true);
    }

    moveDown(e) {
        e.preventDefault();
        this.props.onMove(this.props.id, false);
    }

    render() {
        return (
            <div>
                <h1>I am an Entry inside of a List, hear me roar!</h1>
                <button onClick={this.moveUp}>Move Entry Up</button>
                <button onClick={this.moveDown}>Move Entry Down</button>
            <div>
        );
    }
}
You could also simplify Entry to use a single move event handler if you curried it, or bound the function directly in the onClick attribute and passed the boolean there.

EDIT: An example with a curried move handler:

code:
class Entry extends Component {
    move = up => e => {
        e.preventDefault();
        this.props.onMove(this.props.id, up);
    }

    render() {
        return (
            <div>
                <h1>I am an Entry inside of a List, hear me roar!</h1>
                <button onClick={this.move(true)}>Move Entry Up</button>
                <button onClick={this.move(false)}>Move Entry Down</button>
            <div>
        );
    }
}

Depressing Box fucked around with this message at 22:47 on Jun 23, 2016

necrotic
Aug 2, 2005
I owe my brother big time for this!
edit: whoops, refreshed and there's more!

Yeah, what Depressing Box just posted is the correct way. Your parent should never know about the children state, and vice versa. The idea is to make testing _easier_, not harder.

Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy
Ugh yeah it seems so obvious now. Bind the both the Entry and List event handlers to themselves and then call one from the other. A valuable lesson in managing scope context.

code:
class List extends Component {
	render() {
		return (
			<div>
				{this.state.entries}
			</div>
		);
	}
	handleMove(e, otherThis) {
		console.log(this, otherThis); // List, Entry
	}
}

class Entry extends Component {
	render() {
		return (
			<div>
				<button onClick={this.handleClick.bind(this)}>Click me</button>
			</div>
		);
	}
	handleClick(e) {
		this.props.callback(e, this);
		// or just pass the unique key instead of the context. I GUESS.
	}
}
Thanks!

Revol
Aug 1, 2003

EHCIARF EMERC...
EHCIARF EMERC...
I am building a checklist on Google Sheets for work. The idea is that it will be a template that anyone at my company can open, so that they have this checklist to work through for each of their clients. This was based on the To Do template that Google supplies, which had the cool idea of having a conditional format where if there is anything entered into the check column, that column and the task column are colored gray and are struck out. Very cool.

I want to have it so that anything entered into a cell on the checkmark column is replaced with a check symbol. I believe I should be able to do this using script.google.com, which is Javascript. I found this code:

code:
function onEdit(e) {
if (e.value == “/”) e.range.setValue(“&#10003;”) // e.value is only set when a single cell was edited
}
But I'm getting an error when trying to run the script, saying that there is an illegal character in line 2. I thought it was the checkmark unicode, but I've tried replacing it and the error remains. What am I doing wrong? I don't know how to code, but I do think I know how to read pre-existing code. I'm not seeing why I would get an illegal character error here.

Even if I didn't have this error, the code is incomplete for my needs. I'd need to tell the script to only watch a certain column. And right now it is only looking for a "/" value. I'm not sure how to change it so that it would go off any value.

Depressing Box
Jun 27, 2010

Half-price sideshow.
The first thing that I noticed is your code is using curly quotes ( and ) instead of regular quotes ("), which would cause the "illegal character" error.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Depressing Box posted:

The first thing that I noticed is your code is using curly quotes ( and ) instead of regular quotes ("), which would cause the "illegal character" error.

The perils of using Word as your IDE.

Depressing Box
Jun 27, 2010

Half-price sideshow.
Ok, I put together a simple sanitization script. Note that this is very brittle, and will occasionally miss things like rapid changes or values copied from other cells. You'll probably need to tweak this for your specific setup.

First, go to the sheet's script editor:



Paste in this script:

code:
function onEdit(e) {
  var range = e.range;
  var column = 1;
  var firstRow = 4;
  var checkmark = '\u2713';

  // If the selected cell is...
  if (
    range.getColumn() == column // in the checkmark column
    && range.getRow() >= firstRow // below the header rows
    && e.value.length > 0 // not empty
    && e.value != checkmark // not already a checkmark
  ) {
    // ...replace it with a checkmark.
    range.setValue(checkmark);
  }
}
Save it:



And there you go:



EDIT: Here's are some relevant links from Google's documentation:

Depressing Box fucked around with this message at 19:00 on Jun 24, 2016

Revol
Aug 1, 2003

EHCIARF EMERC...
EHCIARF EMERC...
Oh jeez, that was it.

I also posted this on stack overflow, and I was suggested this code:

code:
function onEdit(e) {
  if (e.range.getColumn() == 4) e.range.setValue("&#10003;");
}
This almost works, but you can't delete any checks. It repopulates immediately. Kinda surprising.

Depressing Box posted:

Ok, I put together a simple sanitization script.

But this script works perfectly. Thanks! Do you have any objects to me posting this in my stack overflow post?

Depressing Box
Jun 27, 2010

Half-price sideshow.
No objects, go nuts.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Mozilla just renamed String.prototype.contains to includes, just in case you have been using that and something is suddenly broken.

Edit: They renamed it a couple of years ago, but removed the old function just now

Wheany fucked around with this message at 20:35 on Jun 26, 2016

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Wheany posted:

Mozilla just renamed String.prototype.contains to includes, just in case you have been using that and something is suddenly broken.

Edit: They renamed it a couple of years ago, but removed the old function just now

I'm sure I have some old production code that that breaks, but I don't work for those people anymore, sooooooo

stoops
Jun 11, 2001
I need to run a form submit, locally, but not using a local webserver.

On my form, a user will select a csv file from their directory, input a title, then click submit. The form should read values from the csv file, spit them out on the page as well as the form title.

I can't use a webserver, or a local webserver.

Is this possible, even with ajax?

I tried googling to read a csv file, but im getting an empty array.

Any help is appreciated.

obstipator
Nov 8, 2009

by FactsAreUseless
You'll want to use a FileReader. This should be able to start you off:
http://www.html5rocks.com/en/tutorials/file/dndfiles/

Depressing Box
Jun 27, 2010

Half-price sideshow.

stoops posted:

I need to run a form submit, locally, but not using a local webserver.

On my form, a user will select a csv file from their directory, input a title, then click submit. The form should read values from the csv file, spit them out on the page as well as the form title.

I can't use a webserver, or a local webserver.

Is this possible, even with ajax?

I tried googling to read a csv file, but im getting an empty array.

Any help is appreciated.

A quick search turned up Papa Parse, which looks promising. It can parse CSV data directly in the browser, including local and remote files.

stoops
Jun 11, 2001
Thanks guys, I have something working right now based on your suggestions

Now, I have a different problem.

Okay, so my studentData variable has to be set like this:

code:
var studentData = [[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]];
I'm generating the [400,3], [450, 5], on the fly, but it turns out that it reads it as

code:
var studentData = ["[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]"];
How can I rid of those extra quotes?

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

stoops posted:

Thanks guys, I have something working right now based on your suggestions

Now, I have a different problem.

Okay, so my studentData variable has to be set like this:

code:
var studentData = [[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]];
I'm generating the [400,3], [450, 5], on the fly, but it turns out that it reads it as

code:
var studentData = ["[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]"];
How can I rid of those extra quotes?

I think you might want to look into how you are generating / reading it in rather than looking at removing the quotes, as that seem to be the better problem to solve.

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

stoops posted:

Thanks guys, I have something working right now based on your suggestions

Now, I have a different problem.

Okay, so my studentData variable has to be set like this:

code:
var studentData = [[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]];
I'm generating the [400,3], [450, 5], on the fly, but it turns out that it reads it as

code:
var studentData = ["[400,3],[450,5],[520,7],[570,22],[640,35],[680,40],[700,23],[770,22],[820,10],[890,5],[910,1],[960,19]"];
How can I rid of those extra quotes?

Could you elaborate on how you are generating the data?

stoops
Jun 11, 2001


Yeah, i know i'm doing it wrong, i just wasnt sure how to put it in the correct array. I'm using this site to read a csv file.

http://evanplaice.github.io/jquery-csv/examples/basic-usage.html


this is the code that reads my csv and spits out a variable

code:
var data = $.csv.toArrays(csv);
var csvData = '';

for(var row in data) {
    csvData += '[';
    csvData += data[row] + '';
    csvData += '],';
 }
I know the problem is there since I'm putting it in a string. I'm just not sure how to go about it putting it in the studentData variable.

this is how i thought I could put it in the studentData variable.

code:
var studentData = [csvData];
I thought I could use push, but I wasn't quite grasping it.

I appreciate the help.

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

stoops posted:

Yeah, i know i'm doing it wrong, i just wasnt sure how to put it in the correct array. I'm using this site to read a csv file.

http://evanplaice.github.io/jquery-csv/examples/basic-usage.html


this is the code that reads my csv and spits out a variable

code:
var data = $.csv.toArrays(csv);
var csvData = '';

for(var row in data) {
    csvData += '[';
    csvData += data[row] + '';
    csvData += '],';
 }
I know the problem is there since I'm putting it in a string. I'm just not sure how to go about it putting it in the studentData variable.

this is how i thought I could put it in the studentData variable.

code:
var studentData = [csvData];
I thought I could use push, but I wasn't quite grasping it.

I appreciate the help.

It's pretty simple then... you are building a string. You just need to parse it back into an object with JSON.parse() . However, if data[row] is your actual data, and not strings, you could skip that step entirely and just do studentData.push(data[row]).

stoops
Jun 11, 2001

Skandranon posted:

It's pretty simple then... you are building a string. You just need to parse it back into an object with JSON.parse() . However, if data[row] is your actual data, and not strings, you could skip that step entirely and just do studentData.push(data[row]).

I"m having trouble with the parsing. I'm just not getting it. I'm getting an error of

code:
VM1942:1 Uncaught SyntaxError: Unexpected number in JSON at position 1
{400,3},{450,5},{520,7},{570,22},{640,35},{680,40},{700,23},{770,22},{820,10},{890,5},{910,1},{960,19},
Do i have to have it a certain way before I can parse it?

necrotic
Aug 2, 2005
I owe my brother big time for this!
Isn't the result of $.csv.toArrays(input) exactly what you want for studentData? I don't think you need to do anything else if you want it as an array of rows and each row is an array of columns.

stoops
Jun 11, 2001

necrotic posted:

Isn't the result of $.csv.toArrays(input) exactly what you want for studentData? I don't think you need to do anything else if you want it as an array of rows and each row is an array of columns.

I thought so, but, the way the data is coming in is like this, (from the console).

code:
[["400","3"],["450","5"]];
That gives me a messed up plot.

What does work is when my values come in as

code:
[[400,3],[450,5]];
Without the quotes.

Just can't figure it out.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



JavaScript code:
var data = $.csv.toArrays(csv);
for(var i = 0; i < data.length; ++i){
    data[i] = data[i].map(val => parseInt(val, 10));
}

Infected Mushroom
Nov 4, 2009
Or do that ^

Infected Mushroom fucked around with this message at 20:42 on Jun 30, 2016

stoops
Jun 11, 2001

Munkeymon posted:

JavaScript code:
var data = $.csv.toArrays(csv);
for(var i = 0; i < data.length; ++i){
    data[i] = data[i].map(val => parseInt(val, 10));
}

That worked, phew. THANK YOU!

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

stoops posted:

That worked, phew. THANK YOU!

Yeah, CSV doesn't encode types so everything is a string. I'm surprised whatever graphing lib didn't handle the coercion for you, though the parseInt approach is definitely better.

You can also use map so you don't have to loop yourself:

code:
var data = $.csv.toArrays(csv).map(row =>
  row.map(val => parseInt(val, 10))
);

LP0 ON FIRE
Jan 25, 2006

beep boop
I have a 2D array with objects and properties. Does anyone know why setting one property at a certain index would set EVERY index with that property? I've checked over and over the validity of the indexes and logged the object just fine.

I do something like: roomArr[currentRoom.x][currentRoom.y].wallUp.icon = 'icons:check-box-outline-blank';

and it sets every "wallUp" property to every index to that icon. It's not going through a loop.

Horn
Jun 18, 2004

Penetration is the key to success
College Slice
How are you setting wallUp? Sounds like you're creating that object once and using it for every item in your array.

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

Horn posted:

How are you setting wallUp? Sounds like you're creating that object once and using it for every item in your array.

Yeah, that sounds about right. You need to either set each wallUp = {x : 1, y: 2, z: 3}, or use a cloning method to ensure they are in fact separate objects.

LP0 ON FIRE
Jan 25, 2006

beep boop

Horn posted:

How are you setting wallUp? Sounds like you're creating that object once and using it for every item in your array.

I'm setting it up with a loop. I know it's fine then. I can check it and see that the objects are different. It's when I change it like in my post above that every object at every index changes.

So to be more clear:

code:
var wallKindArr = {
    solid:    {letter:'s', icon:'icons:indeterminate-check-box'},
    doorway:  {letter:'d', icon:'icons:check-box-outline-blank'},
    locked:   {letter:'l', icon:'icons:lock'},
};

var centerKindArr = {
    key:    {letter:'k', icon:'communication:vpn-key'},
    chest:  {letter:'c', icon:'icons:lock'},
    blank:  {letter:'b', icon:''},
};


var roomArr = new Array(100);
for (var i = 0; i < roomArr.length; i++) {

    roomArr[i] = new Array(100);

    for (var j = 0; j < roomArr[i].length; j++) {
        roomArr[i][j] = { 
            wallUp:    getRandWall(), 
            wallLeft:  getRandWall(), 
            center:    getRandCenter(),
        };

    }

}

function getRandWall(){

    var randWall = Math.floor(Math.random() * Object.keys(wallKindArr).length);

    return wallKindArr[Object.keys(wallKindArr)[randWall]];

}

function getRandCenter(){

    var randCenter = Math.floor(Math.random() * Object.keys(centerKindArr).length);

    return centerKindArr[Object.keys(centerKindArr)[randCenter]];

}
I didn't think so, but this is what you mean by "object once and using it for every item in your array"?

LP0 ON FIRE fucked around with this message at 18:17 on Jul 1, 2016

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

LP0 ON FIRE posted:

I'm setting it up with a loop. I know it's fine then. I can check it and see that the objects are different. It's when I change it like in my post above that every object at every index changes.

The problem is not with the loop, it's that if you do something like below, all the rooms just have pointers to the SAME, single wallUp object that was created, and thus, changing a thing on any of them is going to change it for all of them, as all rooms share a single wallUp object.

code:
var wallUp= { };
var wallDown = { };

for (var x = 0; x < allTheThings;x++) {
	room[x].wallUp = wallUp;
	room[x].wallDown = wallDown;
}
You want something like this, which creates a new object for every room.

code:
for (var x = 0; x < allTheThings;x++) {
	room[x].wallUp = { } ;
	room[x].wallDown = { };
}

LP0 ON FIRE
Jan 25, 2006

beep boop
Looks like that's what I'm doing. Thank you!

Adbot
ADBOT LOVES YOU

Video Nasty
Jun 17, 2003

Is it okay to ask React questions here? I'm not totally grasping a concept and want to figure this out.

A checkbox group can have a parent, global, checkbox that propagates its state to all children. If one of the children is un-checked then the parent should also be. I have two groups of checkboxes and can un-check them all when I un-check the parent, but can't seem to grasp how to get them all checked initially (on the first click) within the same call to this.setState -- the tutorial and documentation have basically gotten me this far: https://jsfiddle.net/x0b1Lzc4/1/ but I don't feel that I'm doing this the React way.

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