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
a dingus
Mar 22, 2008

Rhetorical questions only
Fun Shoe
Ah I get what you mean, not super familiar with JavaScript but that's odd.

Adbot
ADBOT LOVES YOU

camoseven
Dec 30, 2005

RODOLPHONE RINGIN'
That's not odd, that makes sense since edges is an array of nodes. Node isn't an accessible key from the array itself. You'd need to do like products.edges[0].node.title

Also since edges is an array you can do .map or .forEach or whatever to access each node

e:
I dunno poo poo about Svelte and I'm having trouble following what exactly your issue is, but this should work better than 4 loops or whatever:

code:
import { getProducts } from '../../store';

export async function load(ctx) {
    let products = await getProducts();
    return { props: { 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.edges as edge}
				{console.log(edge.node)}
			{/each}
		</div>
	</div>
</div>

camoseven fucked around with this message at 20:38 on Oct 21, 2021

worms butthole guy
Jan 29, 2021

by Fluffdaddy

camoseven posted:

That's not odd, that makes sense since edges is an array of nodes. Node isn't an accessible key from the array itself. You'd need to do like products.edges[0].node.title

Also since edges is an array you can do .map or .forEach or whatever to access each node

e:
I dunno poo poo about Svelte and I'm having trouble following what exactly your issue is, but this should work better than 4 loops or whatever:

code:
import { getProducts } from '../../store';

export async function load(ctx) {
    let products = await getProducts();
    return { props: { 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.edges as edge}
				{console.log(edge.node)}
			{/each}
		</div>
	</div>
</div>


Thank you for the help. I tried that but then I get this as a error :suicide:

code:
500

Cannot read property 'length' of undefined

TypeError: Cannot read property 'length' of undefined
    at Proxy.each (/Users/tl/Desktop/dev/rgc/node_modules/svelte/internal/index.js:1649:31)
    at eval (/src/routes/shop.svelte:27:70)
    at Object.$$render (/Users/tl/Desktop/dev/rgc/node_modules/svelte/internal/index.js:1684:22)
    at Object.default (root.svelte:38:46)
    at eval (/src/routes/__layout.svelte:31:32)
    at Object.$$render (/Users/tl/Desktop/dev/rgc/node_modules/svelte/internal/index.js:1684:22)
    at root.svelte:36:44
    at $$render (/Users/tl/Desktop/dev/rgc/node_modules/svelte/internal/index.js:1684:22)
    at Object.render (/Users/tl/Desktop/dev/rgc/node_modules/svelte/internal/index.js:1692:26)
    at render_response (file:///Users/tl/Desktop/dev/rgc/node_modules/@sveltejs/kit/dist/ssr.js:482:28)

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

camoseven
Dec 30, 2005

RODOLPHONE RINGIN'
I probably missed passing the props to the html since I don't know svelte, so make sure you do that

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Nah you passed it right, I think its just something wonky. I had to do this to get it to kinda work:

code:
	products = products[0].edges;
but that seemed to solve it :)

if I do this:

code:
{#each products as prod}
				{console.log(prod.node.title)}
			{/each}
it works. Is there anyway to destructure it one step more?

fakemirage
Nov 6, 2012

Can't see the haters.

Fixins posted:

it works. Is there anyway to destructure it one step more?
code:
products = products[0].edges.map(edge => edge.node);
That should give you the node elements.
code:
{#each products as product (product.id)}
    <p>{product.title}</p>
{/each}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://svelte.dev/docs#each

fakemirage
Nov 6, 2012

Can't see the haters.

LifeLynx posted:

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.
If you want to write a solution yourself, the basic idea is that you have two copies of whatever you want marquee'd to get the desired effect.
code:
Example: a list of two items "Foo" and "Bar"
            +-- DISPLAY --+
            |+-----+-----+|
            || Foo | Bar ||
            |+-----+-----+|
            +-------------+

By cloning the items you have an identical set of
elements that will show up as the animations starts
            +-- DISPLAY --+    copy
            |+-----+-----++----+-----+
            || Foo | Bar | Foo | Bar |
            |+-----+-----++----+-----+
            +-------------+

Since the elements showing up are identical to
those that exited to the left, it looks like 
they've wrapped around rather than leaving the 
display.
            +-- DISPLAY --+
      +-----+-----+-----+-+---+
      | Foo | Bar | Foo | Bar |
      +-----+-----+-----+-+---+
            +-------------+
        <-- direction

Once the copy of the elements reach the starting
position of the originals you can reset the 
animation (and positions) and start again.
            +-- DISPLAY --+
 +-----+----++-----+-----+|
 | Foo | Bar | Foo | Bar ||
 +-----+----++-----+-----+|
            +-------------+
How you implement this depends a bit on the use case.

You could probably do this in CSS if the elements remains the same throughout the animation and "dumb". If you intend on adding effects or interactivity then it may be easier to write something in JavaScript.

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer

fakemirage posted:

If you want to write a solution yourself, the basic idea is that you have two copies of whatever you want marquee'd to get the desired effect.
code:
Example: a list of two items "Foo" and "Bar"
            +-- DISPLAY --+
            |+-----+-----+|
            || Foo | Bar ||
            |+-----+-----+|
            +-------------+

By cloning the items you have an identical set of
elements that will show up as the animations starts
            +-- DISPLAY --+    copy
            |+-----+-----++----+-----+
            || Foo | Bar | Foo | Bar |
            |+-----+-----++----+-----+
            +-------------+

Since the elements showing up are identical to
those that exited to the left, it looks like 
they've wrapped around rather than leaving the 
display.
            +-- DISPLAY --+
      +-----+-----+-----+-+---+
      | Foo | Bar | Foo | Bar |
      +-----+-----+-----+-+---+
            +-------------+
        <-- direction

Once the copy of the elements reach the starting
position of the originals you can reset the 
animation (and positions) and start again.
            +-- DISPLAY --+
 +-----+----++-----+-----+|
 | Foo | Bar | Foo | Bar ||
 +-----+----++-----+-----+|
            +-------------+
How you implement this depends a bit on the use case.

You could probably do this in CSS if the elements remains the same throughout the animation and "dumb". If you intend on adding effects or interactivity then it may be easier to write something in JavaScript.

Thanks! The diagram was exactly what I was looking for. I couldn't wrap my head around the "math" of it, like when to loop it, how many copies I need, etc. Basically I had trouble wrapping my brain around things not in the viewport.

Armauk
Jun 23, 2021


fakemirage posted:

If you want to write a solution yourself, the basic idea is that you have two copies of whatever you want marquee'd to get the desired effect.
code:
Example: a list of two items "Foo" and "Bar"
            +-- DISPLAY --+
            |+-----+-----+|
            || Foo | Bar ||
            |+-----+-----+|
            +-------------+

By cloning the items you have an identical set of
elements that will show up as the animations starts
            +-- DISPLAY --+    copy
            |+-----+-----++----+-----+
            || Foo | Bar | Foo | Bar |
            |+-----+-----++----+-----+
            +-------------+

Since the elements showing up are identical to
those that exited to the left, it looks like 
they've wrapped around rather than leaving the 
display.
            +-- DISPLAY --+
      +-----+-----+-----+-+---+
      | Foo | Bar | Foo | Bar |
      +-----+-----+-----+-+---+
            +-------------+
        <-- direction

Once the copy of the elements reach the starting
position of the originals you can reset the 
animation (and positions) and start again.
            +-- DISPLAY --+
 +-----+----++-----+-----+|
 | Foo | Bar | Foo | Bar ||
 +-----+----++-----+-----+|
            +-------------+
How you implement this depends a bit on the use case.

You could probably do this in CSS if the elements remains the same throughout the animation and "dumb". If you intend on adding effects or interactivity then it may be easier to write something in JavaScript.
How did you make this diagram?

fakemirage
Nov 6, 2012

Can't see the haters.

Combat Pretzel posted:

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?
Depends on what kind of token we're talking about.

If you have something you can refresh without redoing the full authorization flow (e.g. an OAuth token) you can do the refresh before your request (if you know that the token has, or is about to, expire) or as a response to the server returning a 401 (when you know the token has expired) and then trying your request a second time. Refresh tokens usually last (considerably) longer than your access tokens, so it's just a question of finding where you want to place this in your flow (e.g. with your request, with a hook/interceptor, redux middleware, or something else)

If it's a session stored in a cookie where you can configure the server yourself, then tweaking the session length could be one way to make this less of an issue.

If you don't have access to the server, your best bet is probably the solution you suggest, a timer.

Armauk posted:

How did you make this diagram?
Manually in Visual Studio Code.
Using https://textik.com/ would probably have been faster though.

Sad Panda
Sep 22, 2004

I'm a Sad Panda.
Creating my first page using JavaScript and so doing this by reading things on W3Schools and whatever comes up on Google.

Two really stupid questions...

code:
  x.setAttribute("id", "mySelect");
1. Is it just standard to call all elements before we add them to the DOM x? I'm used to giving all objects a meaningful name, although I guess it's just create + add so it matters less?
2. Is this purely stylistic? The second one seems a lot faster to type. Are there certain attributes that can't be set using properties (which I think is what you'd call the second one..)
code:
  x.setAttribute("id", "mySelect");
code:
x.id = "mySelect";

necrotic
Aug 2, 2005
I owe my brother big time for this!
x is not a standard, use friendly names to your hearts desire.

The attribute functions are less surprising; for example, the class attribute is actually the className property. And if you want to use a non-standard attribute for any reason you must use the functions. I generally prefer the functions for consistency.

Note that with the class attribute there’s a better property to work with: classList.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
TypeScript question. I have a method that accepts some properties for example.

code:
    const body = await getBody({
        arrays: ['ownedPets'],
        numbers: ['age'],
        booleans: ['isFriendly'],
        required: ['name']
    });

    // body ~= {
    //     ownedPets: ['cat'],
    //     age: 23,
    //     isFriendly: false,
    //     name: 'April'
    // }
The result of the method will be structured as you see, where fields specified to be `required` are there (or an error would have been thrown) all are strings, unless specified by the `arrays` `numbers` or `booleans` properties. So...

How can I say "Hey type system, provide intellisense for this madness"?

I'm aware of tricks like the following.

code:
export interface IGetBody {
    (format: BodyOptions & { raw: true, multipart: true }): Promise<RawPart[]>;
    (format: BodyOptions & { raw: true }): Promise<Buffer>;
    (format: BodyOptions & { multipart: true }): Promise<[BodyJson, FilePart[]]>;
    (format?: BodyOptions): Promise<BodyJson>;
}
Some property can change the return type.

But I am not sure how to dig into arrays and say "The returned object has this specific complex structure <blank>." Otherwise I force the user to do it something like the following, hoping there's a way to get TypeScript to help.

code:
    const body = await getBody({
        arrays: ['ownedPets'],
        numbers: ['age'],
        booleans: ['isFriendly'],
        required: ['name']
    }) as Promise<{
        ownedPets: string[];
        age?: number;
        isFriendly: boolean;
        name: string;
    }>;

Nolgthorn fucked around with this message at 13:01 on Oct 29, 2021

fakemirage
Nov 6, 2012

Can't see the haters.

Nolgthorn posted:

But I am not sure how to dig into arrays and say "The returned object has this specific complex structure <blank>."
I'm not that familiar with TypeScript, but I did take a look since the problem seemed pretty interesting.

My initial assumption was that it probably wouldn't work, since you're working with values rather than actual types, but after finding this article describing how to turn a string variable to a dynamic type ("/api/users/:userID/orders/:orderID" into { userID : string; orderID: string; }) I don't see why it wouldn't be possible.

The trick in the article above is that the variable is used as a type.
JavaScript code:
// Modified example from [url]https://www.smashingmagazine.com/2021/01/dynamic-static-typing-typescript[/url]
function get<Path extends string>(
  path: Path,
) {
  // to be implemented
}

get("/reply.php");
// is the same as writing
get<"/reply.php">("/reply.php");
playground

So we could do the same with the arrays you pass in to getBody.
JavaScript code:
function getBody<NumberFields extends string[]>(
  request : {
    numbers : NumberFields
  }
) {
  throw "not implemented!";
}
NumberFields is nothing we define as a new type, it's what we pass to getBody().
e.g. if our call looks like getBody({numbers : ["foo", "bar"]}) we can expect the request to be identical to getBody<["foo", "bar"]>({numbers : ["foo", "bar"]}), right?

Well, no. Unfortunately TypeScript doesn't like us using arrays that can change as types. String works fine, arrays not so much.

You can fix this by explicitly setting the type or making your properties tuples (const & readonly)
JavaScript code:
function getBody<NumberFields extends readonly string[]>(
  request : {
    numbers : NumberFields
  }
) {
  throw "not implemented!";
}
getBody({numbers : ["foo", "bar"] as const})
// is now the same as 
getBody<["foo", "bar"]>({numbers : ["foo", "bar"]})
Once we have our values as types, the return is pretty easy to define (in this stripped example). We want a return that iterates over the type and returns the values (e.g. "foo" and "bar") as keys, and number as type.
JavaScript code:
[K in NumberFields[number]]? : number
// ["foo", "bar"] becomes { foo? : number; bar? : number; }
i.e.
JavaScript code:
function getBody<NumberFields extends readonly string[]>(
  request : {
    numbers : NumberFields
  }
) :
  { [K in NumberFields[number]]? : number } 
{
  throw "not implemented!";
}

const response = getBody({
  numbers : ["foo", "bar"] as const
});
response.foo; // ok
response.bar; // ok
//response.helloWorld // fail
playground

Once we're this far we can start adding new types for our other fields and combine the types in our response.

Where things can get a bit messy is when you start mapping which fields that should be required, arrays, and strings, but it's probably doable.

EDIT: I guess you don't need to do the as const cast if you use the spread operator (...)
JavaScript code:
function getBody<NumberFields extends readonly string[]>(
  request : {
    numbers : [...NumberFields]
  }
) :
  { [K in NumberFields[number]]? : number } 
{
  throw "not implemented!";
}

const response = getBody({
  numbers : ["foo", "bar"]
});
response.foo; // ok
response.bar; // ok
//response.helloWorld // fail
playground

Edit2: Spread introduced some weirdness if you turn the fields optional, but you can fix this by giving it a default value (= []). Not sure readonly is required anymore so we may as well remove it.
JavaScript code:
function getBody<NumberFields extends string[] = []>(
  request : {
    numbers? : [...NumberFields]
  }
) :
  { [K in NumberFields[number]]? : number } 
{
  throw "not implemented!";
}
I've updated the playground with the latest changes.

Edit 3: Wasn't too happy with how the response object looked. I mean it works, but it had needles clutter, especially if you made some fields optional.
JavaScript code:
//const response = getBody({
//  booleans: ["hello", "world"],
//  numbers : ["foo", "bar"],
//  arrays  : ["hello", "foo", "str", "req"],
//  required: ["world", "bar", "fld", "req"]
//});
const response: {
    foo?: number[] | undefined;
} & {
    bar: number;
} & {
    hello?: boolean[] | undefined;
} & {
    world: boolean;
} & {
    req: string[];
    fld: string;
} & {
    str?: string[] | undefined;
}
So to fix this I just extracted the response type and then just copy the types (from the new type) as the response, resulting in:
JavaScript code:
const response: {
    foo?: number[] | undefined;
    bar: number;
    hello?: boolean[] | undefined;
    world: boolean;
    req: string[];
    fld: string;
    str?: string[] | undefined;
}
which I think looks a lot better.
playground

EDIT4: So the above looked promising until I tried creating variables, where it breaks everything.
TypeScript code:
const body = { numbers : ["foo"], arrays : ["bar"] }
const response = getBody(body);
//const response: {
//    [x: string]: number[] | undefined;
//}
This can be fixed by reintroducing as const and readonly, while removing the spread (...) operator, but that also means we're back to where we started.

If there was a way to require the user to type as const then this wouldn't be an issue, but I can't find such a thing.

fakemirage fucked around with this message at 22:39 on Oct 31, 2021

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
Thanks for your help you got much further than I did. I'll have to take another look at this, I gave up completely assuming typescript just wasn't designed to be able to handle it.

Opting instead to ask the user to define a return type, if they wanted the result to be typed.

code:
const body = getBody<Type>({ ...etc });
It's just not ideal because the user is expected to carry an in depth understanding of the utility. When types ideally are supposed to be helping with this kind of thing.

I figure, like you do, things will start to get nonsensical trying to deal with combinations of array and number, for example. To tell typescript "yeah that's an array of numbers". Or required and number, "that's a number that's definitely there."

I fear at this point solving it might only be for academic purposes. If it's possible.

Nolgthorn fucked around with this message at 23:24 on Oct 30, 2021

first move tengen
Dec 2, 2011
I'm working on making a typing test webapp as a project and I've run into a stumbling block with making text scroll automatically. I want text inside a div to appear to scroll or update itself as users type through it. That way, I don't have to restrict myself to only rendering a single paragraph of text.

I thought of a couple ways (that might not work or I don't know how to finish).

1: Put all of the text inside the div to begin with, set overflow to hidden in CSS, and...find some way to push the text up to put old lines out of view and new ones into view. But, since the amount of words on a line depends on the size of the viewport and the passage being rendered, I'm not sure how to shift by exactly one line

2: Use JS to only append just enough text to fill the div at a given time, and remove / add by one line whenever the user types to the end of a line. Similar issue here, I'm not sure how I can get my code to figure out where a line ends or at what point it should remove and append more text

Is either of these ideas a good start? I would appreciate any hints on how I might go about this. It's probably a newbie question but it's my first vanilla JS project ever.

Sad Panda
Sep 22, 2004

I'm a Sad Panda.
Thinking purely logically rather than JavaScript (I'm a newbie too), if you had a monospace font then you'd know how many characters fit on a line. You could then do option 2 and remove /append say 120 characters at a time taking into account where words end.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If you do your rendering via a Canvas, you can use measureText() to figure out how big a line of text will be given your chosen font settings, and use that to inform where you put your line breaks.

Roadie
Jun 30, 2013

first move tengen posted:

I'm working on making a typing test webapp as a project and I've run into a stumbling block with making text scroll automatically. I want text inside a div to appear to scroll or update itself as users type through it. That way, I don't have to restrict myself to only rendering a single paragraph of text.

I thought of a couple ways (that might not work or I don't know how to finish).

1: Put all of the text inside the div to begin with, set overflow to hidden in CSS, and...find some way to push the text up to put old lines out of view and new ones into view. But, since the amount of words on a line depends on the size of the viewport and the passage being rendered, I'm not sure how to shift by exactly one line

2: Use JS to only append just enough text to fill the div at a given time, and remove / add by one line whenever the user types to the end of a line. Similar issue here, I'm not sure how I can get my code to figure out where a line ends or at what point it should remove and append more text

Is either of these ideas a good start? I would appreciate any hints on how I might go about this. It's probably a newbie question but it's my first vanilla JS project ever.

I think you can do all the positioning here in pure CSS.

First, make a div with position: absolute; bottom: 50%;.

Inside that put a div with position: relative; height: 0; max-height: 0; and an unstyled contenteditable div.

Now inside the position: relative div, put a div with position: absolute; top: 0; z-index: -1;. In this inner div, put a full copy of your content, set to color: gray; or whatever.

Now you just need to style the contenteditable div and the inner content div so they produce exactly the same visual output given matching text, but with different text colors.

The end result here should be that the whole arrangement is effectively positioned based on the height of the contenteditable div, which will naturally change as you type into it. The preexisting text is effectively attached to the top of the contenteditable div but floating behind it, so it will automatically scroll up and into view as you type. Then the only JS you need is something that hooks into the contenteditable div and rejects change events that don't exactly match your desired content (so that non-matching keystrokes do nothing).

Everything else past that is just styling the viewport or wrapping elements to hide overflow content and add some nice visual effects (like putting a border and box-shadow on the bottom of the outer absolute-positioned div for a typewriter page look).

This is all off the top of my head, so the approach will probably need experimenting with, but I think it's likely to be less work on the whole than the other approaches.

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

first move tengen posted:

I'm working on making a typing test webapp as a project and I've run into a stumbling block with making text scroll automatically. I want text inside a div to appear to scroll or update itself as users type through it. That way, I don't have to restrict myself to only rendering a single paragraph of text.

I thought of a couple ways (that might not work or I don't know how to finish).

1: Put all of the text inside the div to begin with, set overflow to hidden in CSS, and...find some way to push the text up to put old lines out of view and new ones into view. But, since the amount of words on a line depends on the size of the viewport and the passage being rendered, I'm not sure how to shift by exactly one line

2: Use JS to only append just enough text to fill the div at a given time, and remove / add by one line whenever the user types to the end of a line. Similar issue here, I'm not sure how I can get my code to figure out where a line ends or at what point it should remove and append more text

Is either of these ideas a good start? I would appreciate any hints on how I might go about this. It's probably a newbie question but it's my first vanilla JS project ever.

Can you insert a meaningless element (like an empty span) at the point the user is typing and then use scrollIntoView?

first move tengen
Dec 2, 2011
Thanks for all of these ideas! I like the idea of using a monospace font and will probably actually switch the text over to one. Although it doesn't totally solve my issue because I want the text container to be responsive, so there will still be an undetermined number of characters on a given line based on how large someone makes the window. I might try refactoring everything and rendering with Canvas later on, but for now I'm not comfortable enough with it yet.

I think the latter two ideas might be easier for me to implement right now, so I'll try them out when I get the chance to work on this more. For now I came up with a stopgap solution, where I simply remove the first eight words from the container every eight words successfully typed, once the user has gotten past the first 16 words. It's not exactly what I wanted, but it does basically implement a form of auto scrolling, and it's letting me continue to work on other logic for the app first.

Thanks again, I'm pretty excited to try some of these ideas out!

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer
I thought maybe I could define CSS variables in React, like for example if my stylesheet had this:

code:

.box {
	background: var(--boxColor);
}

If in React I could do something like this:

code:

return (
<div style={'--boxColor': props.boxColor}>Box with BG color</div>
)

And I'd do like

code:

<Box boxColor='#b4d455' />

...to render a box with that color background.

But React doesn't seem to like that because it wants to render the inline style based on the Javascript/JSX version of CSS, not actual CSS. Is there a way to do what I want? That --boxColor variable would control a few different elements, so it would be nice to have.

Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy

LifeLynx posted:

I thought maybe I could define CSS variables in React, like for example if my stylesheet had this:

code:

.box {
	background: var(--boxColor);
}

If in React I could do something like this:

code:

return (
<div style={'--boxColor': props.boxColor}>Box with BG color</div>
)

And I'd do like

code:

<Box boxColor='#b4d455' />

...to render a box with that color background.

But React doesn't seem to like that because it wants to render the inline style based on the Javascript/JSX version of CSS, not actual CSS. Is there a way to do what I want? That --boxColor variable would control a few different elements, so it would be nice to have.

Not really. You could imperatively modify style sheets based on React lifecycle hooks but that would definitely be an anti-pattern in React given your description. If you want to declaratively set component props/values at a broader level I would try something with React Context.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Regarding Redux for React, if I want to avoid rerendering unnecessary things, I need to encapsulate components accordingly?

Right now I have a progress bar to indicate loading and an alert box, sitting in App.jsx, both controlled via Redux, so that I don't need to implement it everywhere and run down all files if I want to change looks. However, everytime I'm changing their state, React will rerender everything. I suppose that'll stop if I shove them into a separate component that's separate from App.jsx?

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

LifeLynx posted:

I thought maybe I could define CSS variables in React, like for example if my stylesheet had this:

code:

.box {
	background: var(--boxColor);
}

If in React I could do something like this:

code:

return (
<div style={'--boxColor': props.boxColor}>Box with BG color</div>
)

And I'd do like

code:

<Box boxColor='#b4d455' />

...to render a box with that color background.

But React doesn't seem to like that because it wants to render the inline style based on the Javascript/JSX version of CSS, not actual CSS. Is there a way to do what I want? That --boxColor variable would control a few different elements, so it would be nice to have.

Set the style as a string.


code:

return (
<div style=‘background: ${props.boxColor}’>Box with BG color</div>
)

Phone posting and I can’t find backtick. Those quotes should be for a template string.

Edit: I am an idiot. You are talking about css variables. This won’t work.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Defining a CSS custom property inside a style prop object seems to work just fine?

https://codesandbox.io/s/quiet-snowflake-eiws1?file=/src/App.js

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer

Ima Computer posted:

Defining a CSS custom property inside a style prop object seems to work just fine?

https://codesandbox.io/s/quiet-snowflake-eiws1?file=/src/App.js

I swear I tried that, you must be a Wizard. Thank you!

LifeLynx
Feb 27, 2001

Dang so this is like looking over his shoulder in real-time
Grimey Drawer
Another hopefully simple question: I've made a React app that takes data from an API containing reviews and spits it out into a nice-looking review feed. I mostly intend to use this for Next.js sites, where React is already built in, but there might be times when I want to put this review feed app into a plain HTML file or a Wordpress site. What's the best way to do that? I know I can include React and React-DOM from a CDN, but I don't know if that's on the right track and/or if I need to somehow combine all the .js chunk files in my build directory into a single .js file. Or possibly build a different way?

Impotence
Nov 8, 2010
Lipstick Apathy
It doesn't matter, you can just iframe the html file and it'll load all the chunks

Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy

Combat Pretzel posted:

Regarding Redux for React, if I want to avoid rerendering unnecessary things, I need to encapsulate components accordingly?

Right now I have a progress bar to indicate loading and an alert box, sitting in App.jsx, both controlled via Redux, so that I don't need to implement it everywhere and run down all files if I want to change looks. However, everytime I'm changing their state, React will rerender everything. I suppose that'll stop if I shove them into a separate component that's separate from App.jsx?
99.9% of the time there is no reason to worry about “unnecessary re-renders”. React is very well optimized such that renders cost virtually nothing in the vast majority of cases. The render loop should be 100% disconnected from Redux in the sense that one does not depend upon the other, so in terms of application state it should not matter how many renders there are (yes even when using hooks). If “extra” re-renders are causing weird issues, unexpected behavior or bugs it’s most likely that you have bad logic and/or anti-pattern render side effects somewhere. In the very very rare case that renders are slow and cause jitter (do not prematurely optimize for this, only when you observe actual slowdowns) you may just need to memorize a component and/or heavy computation somewhere.

Roadie
Jun 30, 2013

LifeLynx posted:

But React doesn't seem to like that because it wants to render the inline style based on the Javascript/JSX version of CSS, not actual CSS. Is there a way to do what I want? That --boxColor variable would control a few different elements, so it would be nice to have.

What you want is Chakra UI.

Sad Panda
Sep 22, 2004

I'm a Sad Panda.
Someone in the make a small apps thread made a project for me. I'm now going to fiddle with it to learn JavaScript and tweak some things.

He made it with everything inside a script tag on the html page.
I decided to move it to a linked .js file rather than be in the script at the bottom of the page.

Everything works, other than these three lines. If I move them to the .js file then they don't seem to run?

code:
document.getElementById('next').addEventListener('click', next);
&#8232;document.getElementById('swap').addEventListener('click', swap);&#8232;
document.getElementById('restart').addEventListener('click', init);&#8232;


When I do, the buttons (next/swap/restart) buttons no longer do anything.

My guess is that it runs the script linked to in the head before the buttons are made? Does that seem a reasonable choice? If so, any suggestions on how to make it happen after the buttons have been added so the eventListeners can be added?

If not, why else might it be?

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
where in the html doc did you include your script? if it's at the top of the html, then yeah the elements haven't rendered yet

JS scripts typically are best placed under the <body /> tag

e: re-read the post. yeah just put it under the body

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


I believe that it needs to be the last tag in the <body>, otherwise it's not HTML5 valid, but that might have changed since the last time I checked.

minato
Jun 7, 2004

cutty cain't hang, say 7-up.
Taco Defender
Add this in the linked script at the bottom. This way the 3 lines of code will get run once the DOM is fully loaded, which is when those elements you're trying to find are sure to exist.
code:
document.addEventListener("DOMContentLoaded", function() {
  document.getElementById('next').addEventListener('click', next);
  document.getElementById('swap').addEventListener('click', swap);
  document.getElementById('restart').addEventListener('click', init);
});

Sad Panda
Sep 22, 2004

I'm a Sad Panda.

teen phone cutie posted:

where in the html doc did you include your script? if it's at the top of the html, then yeah the elements haven't rendered yet

JS scripts typically are best placed under the <body /> tag

e: re-read the post. yeah just put it under the body

Ah thank you for that. I just thought that script links to JS like links to a CSS file go in the head. Is that just a misconception or is there some reason why you would put them in the head?

I moved it down to after the body and all is resolved.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


You can put them in the head if they dont need access to full DOM immediately when loaded. For example, if the the script attaches onload callback to document, and then that callback has access to DOM the way you imagined.

It's just easier to put it and the end, as the last tag in the body. Then you don't need to wrap anything up into event callbacks. It's also been recommended for loading purposes, before defer attribute was a thing, so that the html loads first as it's the part that user sees first.

gbut fucked around with this message at 21:43 on Nov 8, 2021

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

gbut posted:

I believe that it needs to be the last tag in the <body>, otherwise it's not HTML5 valid, but that might have changed since the last time I checked.

yes this i am dumb

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense

fakemirage posted:

I'm not that familiar with TypeScript, but I did take a look since the problem seemed pretty interesting.

Maybe should have posted an update about this earlier. I ended up just offering the option of defining a type, which makes sense considering how complicated any potential solution would be to implement. It's probably a clearer solution anyway.

https://github.com/Kequc/kequapp/blob/main/src/body/create-get-body.ts

code:
export interface IGetBody {
    (format: BodyOptions & { raw: true, multipart: true }): Promise<RawPart[]>;
    (format: BodyOptions & { raw: true }): Promise<Buffer>;
    (format: BodyOptions & { multipart: true }): Promise<[BodyJson, FilePart[]]>;
    (format?: BodyOptions): Promise<BodyJson>;
    <T>(format: BodyOptions & { multipart: true }): Promise<[T, FilePart[]]>;
    <T>(format?: BodyOptions): Promise<T>;
}
So it ends up being I catch the important stuff, like where the basic structure of the returned value changes with some key values and the rest is returned as either just your basic key value pairs, or if specified an object of a defined shape.

code:
type MyStructure = {
    foo?: number[];
    bar: number;
    hello?: boolean[];
    world: boolean;
    req: string[];
    fld: string;
    str?: string[];
};

const result = await <MyStructure>getBody({
    booleans: ["hello", "world"],
    numbers : ["foo", "bar"],
    arrays  : ["hello", "foo", "str", "req"],
    required: ["world", "bar", "fld", "req"]
});
Then it's just a matter of providing good documentation of what type of object the user should expect back, and letting them define the type if they want to.

Adbot
ADBOT LOVES YOU

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
I went through builtins.h of V8 earlier, and found out about this Temporal thing.

For the love of god, hurry up finishing this proposal and turn it into a loving standard already.

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