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
Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Haystack posted:

So I'm looking for a resource to help my wife get up to speed with browser javascript. Just a basic, solid introduction to ES6. She learns best by tinkering, so I'm thinking something that has a lot of interactive code and example projects to mess with. She's got a fair amount of experience with PHP so it doesn't have to be bare basics. Any suggestions?

I have seen this recommended a lot by people, and a quick glance at it doesn't raise any flags: https://eloquentjavascript.net/

Adbot
ADBOT LOVES YOU

a dingus
Mar 22, 2008

Rhetorical questions only
Fun Shoe

Lumpy posted:

I have seen this recommended a lot by people, and a quick glance at it doesn't raise any flags: https://eloquentjavascript.net/

I read through this while building an API in node and I would recommend it. Coming from a python background it was easy to pick up JavaScript with this book. I also liked You Don't Know JS Yet by Kyle Simpson.

MREBoy
Mar 14, 2005

MREs - They're whats for breakfast, lunch AND dinner !
I'll keep this short, I'm looking for some NodeJS app fixing help, I put a blurb in the Goons for Hire thread.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice
Typescript shenanigans:

Using GraphQL we manually mode types for things we'd get back from queries:

JavaScript code:
type Thing = {
  someProp: PropValue;
}

enum PropValue {
  THIS_VALUE = 'THIS_VALUE',
}
and all is well.

However, auto-generating types from the graphQL schema / queries itself was added, and was doing great for new stuff. However it generates types like so:

JavaScript code:
type Thing = {
  someProp: PropValue;
}

enum PropValue {
  ThisValue = 'THIS_VALUE', // note!!
}
So if you are using "old" components that take a Thing it doesn't work, since the someProp on it doesn't match.

Is there a way to convert one enum to another or use them interchangeably? The plan is to make the auto-gen enums use PROPER_CASE, but trying to temporarily get one thing working before embarking on the headache of updating code all over the place.

EDIT: I did this, and it seems to work:

JavaScript code:
import { PropValue } from "new/generated/types";
import { PropValue as OldPropValue } from "older/handmade/types";

const thing: Thing = {
  someProp: PropValue.ThisValue, // gql generated style...
}
<ComponentThatUsesOldPropValueEnumInternally
  propValue={ thing.someProp as string as OldPropValue }
/>
:woop:

Lumpy fucked around with this message at 18:48 on Sep 21, 2021

Sous Videodrome
Apr 9, 2020

Haystack posted:

So I'm looking for a resource to help my wife get up to speed with browser javascript. Just a basic, solid introduction to ES6. She learns best by tinkering, so I'm thinking something that has a lot of interactive code and example projects to mess with. She's got a fair amount of experience with PHP so it doesn't have to be bare basics. Any suggestions?

It's not really a course but I like w3schools tutorials:

https://www.w3schools.com/js/DEFAULT.asp

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:
I wrote a personal project for the web but I want to make a command-line version (it's a password generator). Being lazy I don't feel like rewriting it in Python or bash or whatever, so I tried rhino, which works except that I'd like to interact with the clipboard. I'm not finding much that would suggest it's possible without the browser (navigator.clipboard.writeText) but figured I'd ask. Basically I want to do

$ pw some_seed_value

and have the generated password written to the clipboard rather than flopped out on the terminal for all to see. If it's not obvious, I'm in a Linux environment.

Impotence
Nov 8, 2010
Lipstick Apathy
https://github.com/sindresorhus/clipboardy something like this

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:
grr, npm I was hoping to keep this under 60GB...

Edit, why use one language when you can use two:

#!/bin/bash
pwjs $1 $2 $3 | xsel -i

Tad Naff fucked around with this message at 06:13 on Sep 26, 2021

fuf
Sep 12, 2004

haha
this jquery question might not make sense because I dunno wtf I'm doing but...

I have an ajax call that gets the contents of a simple html page:

JavaScript code:
 $.ajax({
               type: "GET",
               url: "/get-titles/",
               success: function(result){
                    console.log(result);
               }
          });
the result looks something like:

code:
<body>
<ul>
<li>title 1</li>
<li>title 2</li>
<li>title 3</li>
</ul>
</body>
I want to turn this into an array like ['title1', 'title2', 'title3']

With jquery I could do something like:
JavaScript code:
var titles = [];
$('li').each(function(){
        titles.push($(this).text());
    });
But like how do I run this jquery against the return of my ajax call? The html isn't actually in the DOM, it's just in that "result" object.

I basically want:
JavaScript code:
 
var titles = [];
$.ajax({
               type: "GET",
               url: "/get-titles/",
               success: function(result){
			$('li').each(function(){ // SOMEHOW MAGICALLY SELECT <li> ELEMENTS WITHIN result RATHER THAN MAIN PAGE
        			titles.push($(this).text());
    			});
               }
          });
Does that make any sense and is it possible?

EDIT: lol I think I was overthinking this a bit. I just had to load the result into a random hidden div and then do my thing on that:

JavaScript code:
var titles = [];
$.ajax({
               type: "GET",
               url: "/get-titles/",
               success: function(result){
			$('#holder').html(result);
			$('#holder li').each(function(){
        			titles.push($(this).text());
    			});
               }
          });
Oh well typing out the question helped me think it through :)

fuf fucked around with this message at 17:38 on Sep 27, 2021

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
It's a bad practice to make a request to a URL that produces HTML markup in the first place, since it means you have to scrape the actual content you want out of the markup.

It's also dangerous to write the contents of the response as HTML to your page in order to "parse" it. Doing so opens you up to potential code execution attacks, such as if there is a script tag present (and there are numerous other ways to trigger script execution without a script tag too)

If there's really no way around making a request to a page full of HTML, there are better and safer ways to accomplish it, like the DOMParser API:

JavaScript code:
(async () => {
  // fetch the html as a string
  const response = await fetch('/get-titles/');
  const responseText = await response.text();
 
  // parse the html into an HTMLDocument without writing it to the page
  const parser = new DOMParser();
  const responseDocument = parser.parseFromString(responseText, 'text/html');
  
  // query-select all the <li> tags and extract their innerText to store in an array
  const titles = Array.from(responseDocument.querySelectorAll('li')).map((el) => el.innerText);
 
  // log output
  console.log(titles);
})();

Impotence
Nov 8, 2010
Lipstick Apathy
Since it's using $.each I assume it's some horrifically legacy codebase that just needs to stay alive in maintenance mode.

That being said, you can also do something like $('li', $(yourHtmlString).context).each() instead of appending it to the page

fuf
Sep 12, 2004

haha
it's a random little project running completely locally so no real concerns about security or bad practice

is $.each totally out of date or something?

Impotence
Nov 8, 2010
Lipstick Apathy
Pretty much 99% of jquery is now part of the standard

$("li").each -> document.querySelectorAll("li").forEach, for example

Roadie
Jun 30, 2013

Biowarfare posted:

Pretty much 99% of jquery is now part of the standard

$("li").each -> document.querySelectorAll("li").forEach, for example

Note that for dumb legacy reasons you can use forEach there but not map, so you'll often want to do <fixed>[...document.querySelectorAll("li")]</fixed> so you can just treat it like a normal array with all the normal array stuff.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
When I have multiple modules with loose Javascript statements in the main body (in Node.JS), outside of a function, as long these modules are somehow referenced, will that code execute when the application starts up? What about static class constructors? I'm wondering if it's possible to implement some self-registering semantic for endpoints of my web service. Or what's a good way to go about it?

Ytlaya
Nov 13, 2005

There's something a coworker did that I think is unnecessary, but I want to double-check that I'm not going crazy here (since these coworkers are generally more competent than me at most programming tasks, but I'm starting to wonder if they might lack some really basic javascript/html stuff).

Basically the guy in question put some controls for a feature inside of a form element, but the form element does nothing and is never submitted (and as far as I can tell never will be). All functionality is just controlled by the JS and the only submission is an AJAX request (whose parameters are also just pulled from the html using JS). Putting stuff inside of a form that is never being submitted doesn't make sense, right?

fsif
Jul 18, 2003

Ytlaya posted:

There's something a coworker did that I think is unnecessary, but I want to double-check that I'm not going crazy here (since these coworkers are generally more competent than me at most programming tasks, but I'm starting to wonder if they might lack some really basic javascript/html stuff).

Basically the guy in question put some controls for a feature inside of a form element, but the form element does nothing and is never submitted (and as far as I can tell never will be). All functionality is just controlled by the JS and the only submission is an AJAX request (whose parameters are also just pulled from the html using JS). Putting stuff inside of a form that is never being submitted doesn't make sense, right?

I believe you'd want to keep the form element there for semantic/screen reader reasons.

Dancer
May 23, 2011

fsif posted:

I believe you'd want to keep the form element there for semantic/screen reader reasons.

This 100%, and some people (like me) consider this a major issue.

Cugel the Clever
Apr 5, 2009
I LOVE AMERICA AND CAPITALISM DESPITE BEING POOR AS FUCK. I WILL NEVER RETIRE BUT HERE'S ANOTHER 200$ FOR UKRAINE, SLAVA
+1 to using the form element for the semantic intent. The AJAX submission is still a submission. Using the form's native submission behavior is not the decider on when form should be used.

I had the damnedest time trying to convince some mobile engineers who got merged into my web-focused team to use semantic anything and they just ended up ignoring me. Now none of our input elements have labels associated with them :shepicide:

Ytlaya
Nov 13, 2005

fsif posted:

I believe you'd want to keep the form element there for semantic/screen reader reasons.

Ah thanks, I hadn't considered that.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


Cugel the Clever posted:

I had the damnedest time trying to convince some mobile engineers who got merged into my web-focused team to use semantic anything and they just ended up ignoring me. Now none of our input elements have labels associated with them :shepicide:

Just start filling up the backlog with bugs that link to git blame on the specific lines that miss the attributes. That'll make you popular really fast.

Roadie
Jun 30, 2013

fsif posted:

I believe you'd want to keep the form element there for semantic/screen reader reasons.

Also basic ease-of-development stuff, like hooking onto the onsubmit event on the form meaning that you don't have to add individual keyboard event handlers to everything to support using the enter key properly.

is that good
Apr 14, 2012
If it fits what you need to do, you can also feed the form element to the FormData constructor to have it do some of the work of generating name-value pairs for you.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Do Javascript or its specific runtimes happen to have an intrinsic to quickly hash strings, for implementing fast custom hash tables or poo poo like that?

Munkeymon
Aug 14, 2003

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



Node has https://nodejs.org/dist/latest-v14.x/docs/api/crypto.html#crypto_class_hash but it doesn't have the equivalent of hashCode in Java or GetHashCode in .Net. This being an interpreted language you can alway monkey patch it in though: https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
I'm using that one already for creating hashes of database queries and parameters for caching. So that one runs faster than a pure JS implementation then?

Munkeymon
Aug 14, 2003

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



Which one?

I'd guess one of the answers from SO would be faster because there's probably both overhead in calling out to native code and 'extra' algorithmic complexity when doing cryptographically sound one-way hashes if you're using the crypto module in Node. That'd be pretty easy to benchmark, though.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
i'm having a senior moment....how do I perform a POST fetch with a body like this in postman?

code:
POST [url]https://api.igdb.com/v4/characters[/url]

Body:
fields games.*;
where name = "Kratos";
so i figured itd be something like

code:
const data = { fields: 'games.*' };

fetch('https://example.com/profile', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
  console.log('Success:', data);
})
.catch((error) => {
  console.error('Error:', error);
});


but I have no clue how to handle the where and the fields. thanks for any help

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Fixins posted:

but I have no clue how to handle the where and the fields. thanks for any help
If the server understands the format you posted then you want to replace
code:
  body: JSON.stringify(data),
with
code:
  body: 'fields games.*;\nwhere name= "Kratos";'
(Or an equivalent stringification)

Body doesn't have to be json, that's just a commonly used way of making it easily parseable across different languages and platforms.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Ahhh okay cool. The server accepts JSON too but all their tutorials use raw text. :shrug:

now to figure out how to get ESlint to stop removing the ' around Authorization :suicide:

EVIL Gibson
Mar 23, 2001

Internet of Things is just someone else's computer that people can't help attaching cameras and door locks to!
:vapes:
Switchblade Switcharoo

Fixins posted:

Ahhh okay cool. The server accepts JSON too but all their tutorials use raw text. :shrug:

now to figure out how to get ESlint to stop removing the ' around Authorization :suicide:

I found this suggestion about http Authorization header and how to modify the eslint to stop doing it.

https://github.com/prettier/prettier-vscode/issues/172

I am only responding because I do web app security testing and whenever I see Authorization headers, I just want to stop testing.

It always turns out I need to set up a bunch of new cookie jars and slow testing because it can always get hosed if a different dev developed a different part of the application.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
What's a good semantic to deal with user sessions and authentication in a React SPA?

Right now, when the user loads the page, the App.jsx "frame/wrapper" checks with upstream whether the authentication token is still valid and either renders the login form or the React Router routing stuff. If said token times out, so far how I have things, it'll break the application (one reason I guess because things closer to the root of the DOM don't have a need to re-render and the effects don't run).

How to handle this better? Just run a timer that refreshes the token/session in background, so long the application is open in the browser?

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer
Already posted this in the general web dev thread, but I meant to post in this probably more relevant thread. Oops.

I'm trying to get an infinite "marquee" of logos going, but I can't find anything for it in React. Something like this: https://www.apple.com/apple-tv-plus/ with the marquee/carousel of shows. I'd like to do it in React Spring or Framer Motion, because I plan on trying that for other animations and I'd like to keep from installing too many things.

Here's a codesandbox for a Framer Motion attempt: https://codesandbox.io/s/stupefied-lamarr-mqlvk

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Objects drive me fukkin insane. I'm trying to use the Shopify API and I get the following as a response:

code:
{
  "edges": [
    {
      "node": {
        "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzczNDE3MDU3NTY4ODU=",
        "handle": "dragon-quest-ix-nintendo-ds",
        "description": "Game is Complete with Box, Manual & Game. Wear shown on manual. Description Tasked with protecting a village, the player character along with other angels (celestials) are attempting to reach God's land. By helping and protecting his town and earning their thanks, the main character obtains enough benevolence for the World Tree to produce the Goddess Fruit. This fruit is the only sure way to enter God's land. Things don't go according to plan, taking the player into the adventure proper.Dragon Quest IX marks a number of firsts for the series: it is the first title to be initially launched for a handheld system and to have no real random encounters (unless travelling over sea). Instead the player can see the enemies on the map. Even though the game isn't the first main series title in 3D, for the first time all equipable items are visible on the characters models at all times.Furthermore, the game was created with the intent of having a multiplayer focus: players can bring their adventurers into their friends' worlds via wireless connection to play alongside them and even swap copies of their heroes which may bring special items like treasure maps with them. There's also downloadable content available through Wi Fi, like new items and quests.Similar to previous titles, combat is turn-based, where the player selects tasks for each of the characters: attack, use item, cast a spell etc. Like in Dragon Quest III, all party members are created by the player; unlike the hero, they don't fulfil specific roles in the narrative and may be swapped at a special service available at inns.",
        "title": "Dragon Quest IX - Nintendo DS",
        "totalInventory": 2,
        "productType": "Nintendo DS",
        "variants": {
          "edges": [
            {
              "node": {
                "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC80MTkxMzYzMTE0NjE5Nw==",
                "title": "Default Title",
                "quantityAvailable": 2,
                "price": "58.00"
              }
            }
          ]
        },
        "priceRange": {
          "maxVariantPrice": {
            "amount": "58.0",
            "currencyCode": "USD"
          },
          "minVariantPrice": {
            "amount": "58.0",
            "currencyCode": "USD"
          }
        },
        "images": {
          "edges": [
            {
              "node": {
                "src": "https://cdn.shopify.com/s/files/1/0604/2897/6341/products/PXL_20211020_134800545.jpg?v=1634738442",
                "altText": null
              }
            }
          ]
        }
      }
    },
    {
      "node": {
        "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzczNDE4MjUzOTI4NTM=",
        "handle": "snatcher-sega-cd",
        "description": "Game is Complete with Box, Manual(s), Insert & Disc. Snatcher is set in the futuristic Neo Kobe City, a city of madness and decadence. The year is 2047 (or 2042, according to the original Japanese version). Mankind is facing its gravest crisis. A mysterious bio-roid life form has appeared. Its true nature and purpose are unknown. Is it some country's secret weapon, or an alien from another world? They appear in the winter, killing people and taking their place in society. They wear artificial skin and can sweat and even bleed. They are called \"Snatchers\" because they \"snatch\" their victims before they take their place.A new police force, specifically trained to fight the Snatchers, has been formed. They are JUNKERs (which is deciphered as \"Japanese Undercover Neuro-Kinetic Elimination Rangers\" in the English version). Every time you encounter someone, a difficult question must be asked — is it a person or a snatcher? The player takes control of Gillian Seed, one of the JUNKERs. The gameplay largely follows the structure of a Japanese-style adventure. The player uses a menu-driven interface to execute commands, which include moving between locations and interacting with the environment. Typically, every room contains objects that can be examined, leading to text descriptions and comments. Conversations occupy a large portion of the gameplay, with various topics available and a wealth of information about the game's world and characters. A few parts contain light puzzle-solving elements, though as a rule the game is almost completely devoid of puzzles.During key moments of the narrative, the player will be prompted to participate in intense shooting sequences. The goal is usually to kill all the enemies that pop out on the screen before they are able to kill Gillian. Some of such sequences are timed, i.e. the player is required to quickly shoot before another events is triggered, leading to the protagonist's death.",
        "title": "Snatcher - Sega CD",
        "totalInventory": 1,
        "productType": "Sega CD",
        "variants": {
          "edges": [
            {
              "node": {
                "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC80MTkxNDM1OTQxNDk5Nw==",
                "title": "Default Title",
                "quantityAvailable": 1,
                "price": "1500.00"
              }
            }
          ]
        },
        "priceRange": {
          "maxVariantPrice": {
            "amount": "1500.0",
            "currencyCode": "USD"
          },
          "minVariantPrice": {
            "amount": "1500.0",
            "currencyCode": "USD"
          }
        },
        "images": {
          "edges": [
            {
              "node": {
                "src": "https://cdn.shopify.com/s/files/1/0604/2897/6341/products/142896-snatcher-sega-cd-front-cover.jpg?v=1634775255",
                "altText": null
              }
            }
          ]
        }
      }
    }
  ]
}
SvelteKit uses a each x as y to run a loop over a array. Which produces the above, but I need to be able to access what should be product.edges.node.title...but when I try to do that I get a undefined error. Any idea how I access that? Thanks :(

Here is the code I have so far:

code:
	import { getProducts } from '../../store';
	export async function load(ctx) {
		let products = await getProducts();
		return { props: { products } };
	}



	export let products = [];
	products = Object.values(products);


<div class="mainContent">
	<div class="contentBlock">
		<div class="RULES">
			<img src="/image0.jpeg" alt="Hentai Free since 20201" />
		</div>
		<div class="gameShelf">
			{#each products as prod}
				{console.log(prod.edges[0].node)}
			{/each}
		</div>
	</div>
</div>
I was attempting this tutorial https://blog.logrocket.com/build-ecommerce-site-sveltekit-shopify-apis/ but I can't get the graphql / whatever to return data as a array so I have to convert it

worms butthole guy fucked around with this message at 03:05 on Oct 21, 2021

worms butthole guy
Jan 29, 2021

by Fluffdaddy
I don't know if this will help but this is how many loops I had to run in order to get my desires result:


code:

<div class="gameShelf">
			{#each products as prod}
				{(prod = Object.values(prod))}
				{#each prod as pre}
					{#each pre as fin}
						{(fin = Object.values(fin))}
						{#each fin as ouch}
							<p>{ouch.title}</p>
						{/each}
					{/each}
				{/each}
			{/each}
		</div>


4 loops !!

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen

Fixins posted:

4 loops !!

In such situations, my pattern is to add a helper function to extract, process, derive, flatten & adapt poorly formed data into a clean form for the UI.

code:
export let trash_data;

const process = (data) => {
    // ....
};
$: wellformed_data = process(trash_data);

// {#each wellformed_data as [...]}
I make the process function a generator if the data-set is of unknown size.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

ynohtna posted:

In such situations, my pattern is to add a helper function to extract, process, derive, flatten & adapt poorly formed data into a clean form for the UI.

code:
export let trash_data;

const process = (data) => {
    // ....
};
$: wellformed_data = process(trash_data);

// {#each wellformed_data as [...]}
I make the process function a generator if the data-set is of unknown size.

This is very good and smart advice. Even if your data comes back magically in the perfect shape for your UI, you should still create that function and just have it do nothing. When then data shape from the server changes, and it will, you will be happy you did.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Oh sweet thanks for that I'm going to try it. I should just run the four loops in that function then, right

worms butthole guy fucked around with this message at 15:35 on Oct 21, 2021

a dingus
Mar 22, 2008

Rhetorical questions only
Fun Shoe
It looks like edges is an array, so you couldn't access it via product.edges.node.title?

Adbot
ADBOT LOVES YOU

worms butthole guy
Jan 29, 2021

by Fluffdaddy
No it returns as undefined oddly

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