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
Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
Node http is really interesting, it's poorly documented and feels like it isn't very well cared for.

I'm playing around with `http.createServer((req, res) =>` in conjunction with `const req = http.request((res) =>` which to the naked eye looks straight forward enough. You've got a server that deals with an incoming `req` and outgoing `res`, and you've got a request that deals with an outgoing `req` and incoming `res`.

However the context through which these `req` and `res` objects are created causes them to behave differently and have totally different apis.

For one thing, `createServer` waits for a `req` that inherits from `stream.Readable` and a `res` that inherits from `stream.Writable` whereas `request` is generating `req` and `res` objects which inherit from the opposite. But that isn't enough, because half of the methods that are supposed to be available on either of them disappear.

The node documentation explicitly states that these objects are identical, `<http.ClientRequest>` and `<http.ServerResponse>`. But gets murky about what they inherit from, saying that they inherit from `<Stream>` which isn't an actual thing. You've got four different types of `Stream` there's no singular `Stream` class.

Regardless why aren't the methods intact the documentation says are there? Why am I dealing with this crap api, on a developer tool that's that's completely ubiquitous? It's on version 15 now.

Adbot
ADBOT LOVES YOU

Impotence
Nov 8, 2010
Lipstick Apathy

Good Sphere posted:

Exactly what I needed. Thank you.

Now to see how this compression holds up to my own. I'm suspicious as a more noisy image only compressed down to 396/400.

Information theory and all, compressing a mp3 or jpg won't get you much gains or might even get you losses. Compressing a bmp or something on the other hand

oh no computer
May 27, 2003

I'm trying to get my head around redux (with react) and something isn't quite clicking. I've built a simple little test app that makes calls to JSONPlaceholder (I'm using redux-thunk to deal with async requests) to grab some dummy posts and list them within a PostList component. A post contains information about the post and then the userid of the author, so what I'm trying to do is for each post, have a separate UserDetail component that takes the ID and then makes a request to /users/{id} to grab the user details so that I can display say the username. I've got it working in as much as it can display properly but my app is doing far too much unnecessary work: for each post a new user is added to the store regardless of whether that particular user is already in it, and it's making a separate API request to /users for each post. So for the sample list of 100 posts that have 10 posts each for each user, I'm ending up with 10 API requests to /users/1, 10 requests to /users/2 etc, and my users array in the store ends up being 100 entries large despite there only being 10 unique users. I'm trying to refactor it so that it only makes an API request for the user details + add the user to the store if said user doesn't already exist in the store, but I can't get it to work.

code:
// reducer code
const userReducer = (users = [], action) => {
  if (action.type === 'FETCH_USER') {
    return [...users, action.payload];
  }
  return users;
};
export default combineReducers({
  posts: postReducer, // my other reducer for fetching the posts
  users: userReducer
});
code:
// my action creator code
export const fetchUser = id => {
  return async (dispatch, getState) => {
    // The following line is what I've added to try to make it work, but it's just doing all the requests anyway
    if (!getState().users.find(user => user.id === id)) {
      const response = await JSONPlaceholder.get(`/users/${id}`);
      dispatch({ type: 'FETCH_USER', payload: response.data });
    }
  };
};
code:
// UserDetail.js (gets passed userID as a prop from PostList.js)
class UserDetails extends React.Component {
  componentDidMount() {
    this.props.fetchUser(this.props.userID);
  }
  render() {
    const { user } = this.props;
    if (user) {
      return (
        <div className="header">
          { user.name }
        </div>
      );
    }
    return <div>Awaiting user info</div>;
  }
}
const mapStateToProps = (state, ownProps) => {
  const currentUser = state.users.find(user => user.id === ownProps.userID);
  return { user: currentUser };
};
export default connect(mapStateToProps, { fetchUser })(UserDetails);
I'm guessing it's probably something about the component lifecycle that I'm missing, either that or I just haven't got my head around how all this poo poo fits together. The tutorial I'm following suggests installing lodash in order to make use of its memoize function but surely there must be a way of doing something so simple without that?

MrMoo
Sep 14, 2000

Nolgthorn posted:

Node http is really interesting, it's poorly documented and feels like it isn't very well cared for.

That’s pretty much a summary for anything not in v8. Like the fetch api has been around for ages, but Node hasn’t picked it up.

I have a complex app that both serves and requests HTTP using the Node HTTP API and implements transparent compression, chunking, and SSE. So in some regard flexible, but then the Node team built HTTPS and HTTP/2 as entirely separate modules which is really annoying. Expecting the same with HTTP/3.

Obfuscation
Jan 1, 2008
Good luck to you, I know you believe in hell

oh no computer posted:

code:
// reducer code
const userReducer = (users = [], action) => {
  if (action.type === 'FETCH_USER') {
    return [...users, action.payload];
  }
  return users;
};

The reducer here is why all of your users are getting added to the store after every request, you need some logic here that merges the new users with the already stored ones based on userId or something. Also throw some console.logs to check that the userId gets passed all the way to the action, because if it's null or something then you will actually get all the users in the response.

oh no computer
May 27, 2003

Obfuscation posted:

you need some logic here that merges the new users with the already stored ones based on userId or something
I've amended the reducer so that it performs a lookup for each incoming user and only appends a user to the store if they aren't already in it, and that's fixed the issue with my users array being 10x too large with duplicated data, but I'm still making 10x as many API requests...

Obfuscation posted:

throw some console.logs to check that the userId gets passed all the way to the action, because if it's null or something then you will actually get all the users in the response.
...I think this is it, I've tried console.logging getState().users in the fetchUser action, and users is an empty array every time it runs, meaning that getState().users.find() always returns undefined . How come the array hasn't been populated at the time the action gets called? Is this possibly a lifecycle thing/an async thing?

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Since I'm now rewriting some of our apps in Javascript and want to use Electron, but everything's xcopy deployments and I don't want to update every Electron runtime per app, I figured install one in a central location and feed it the path to the node app. That seems to work apparently fine. Any drawbacks with that? Could this work with asar files, too? --edit: Nevermind, just feed it the path to the asar instead of the project folder. So easy. :doh:

Combat Pretzel fucked around with this message at 18:17 on Mar 3, 2021

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Thank you thank you so much goons for helping me get my program running :D. I ended up having to use Apollo Client to run my api within a component since Nextjs doesn't support doing it without something like APollo.

Anyways, now I have a weird issue where in order to update state, I have to click a button twice. Anyone know how to fix something like that? Here's my code for that section, trimmed of all the extra stuff:

code:

0]]]
import { useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { useRouter } from "next/router";
import { useQuery, useLazyQuery, gql } from "@apollo/client";

export default function SearchBox({
  viewport,
  setViewport,
}) {
  const router = useRouter();
  const { query } = router;

  const [getCamps, { loading, error, data }] = useLazyQuery(MAP_CITY_DATA, {
    variables: {
      string: query.city,
    },
  });

  const citycamps = data;

  const handleSubmit = async (values) => {
    getCamps();
    const lat = parseFloat(
      citycamps.campgrounds.nodes[0].acfDetails.latitude.toFixed(4)
    );
    const long =
      Math.abs(
        parseFloat(
          citycamps.campgrounds.nodes[0].acfDetails.longitude.toFixed(4)
        )
      ) * -1;

    setViewport({
      ...viewport,
      latitude: citycamps ? lat : 44.43,
      longitude: citycamps ? long : -72.352,
      bearing: 0,
      pitch: 20,
      zoom: 11,
    });
    
    router.push(
      {
        pathname: "/camps",
        query: { ...values, page: 1 },
      },
      undefined,
      { shallow: true }
    );
  };

return(
<Button
                  color="primary"
                  variant="outlined"
                  type="button"
                  fullWidth
                  onClick={submitForm}
                >
                  Search Campgrounds
                </Button>)

I tried to google search it but every answer seems unrelated to what i'm doing...I think. Excuse my messy unorganized code. Thanks for the help!

Chas McGill
Oct 29, 2010

loves Fat Philippe
Where is submitForm declared? Should that be handleSubmit?

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS

Chas McGill posted:

Where is submitForm declared? Should that be handleSubmit?

Sorry forgot to include that, that's a prop for Formik


code:
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
      {({ values, submitForm }) => (
        <Form>
          <Paper className={classes.paper} elevation={5}>
            <Grid container spacing={3}>
              <Grid item xs={12} sm={smValue}>
                <FormControl fullWidth variant="outlined">
                  <InputLabel id="search-region">Region</InputLabel>
                  <Field
                    name="region"
                    as={Select}
                    labelId="search-region"
                    label="Region"
                  >
                    <MenuItem value="all">
                      <em>All</em>
                    </MenuItem>
                    {regions.nodes.map(region => {
                      return (
                        <MenuItem key={region.id} value={region.name}>
                          {region.name}
                        </MenuItem>
                      );
                    })}
                  </Field>
                </FormControl>
              </Grid>

              <Grid item xs={12} sm={smValue}>
                <FormControl fullWidth variant="outlined">
                  <InputLabel id="search-type">Type</InputLabel>
                  <Field
                    name="camptype"
                    as={Select}
                    labelId="search-type"
                    label="Type"
                  >
                    <MenuItem value="all">
                      <em>All</em>
                    </MenuItem>
                    {camptypes.nodes.map(camp => {
                      return (
                        <MenuItem key={camp.id} value={camp.name}>
                          {camp.name}
                        </MenuItem>
                      );
                    })}
                  </Field>
                </FormControl>
              </Grid>

              <Grid item xs={12} sm={smValue}>
                <FormControl fullWidth variant="outlined">
                  <InputLabel id="search-feat">Features</InputLabel>
                  <Field
                    name="campfeatures"
                    as={Select}
                    labelId="search-feat"
                    label="Features"
                  >
                    <MenuItem value="all">
                      <em>All</em>
                    </MenuItem>
                    {features.nodes.map(cf => {
                      return (
                        <MenuItem key={cf.name} value={cf.name}>
                          {cf.name}
                        </MenuItem>
                      );
                    })}
                  </Field>
                </FormControl>
              </Grid>

              <Grid item xs={12} sm={smValue}>
                <FormControl fullWidth variant="outlined">
                  <InputLabel id="search-cities">City</InputLabel>
                  <Field
                    name="city"
                    as={Select}
                    labelId="search-cities"
                    label="Cities"
                  >
                    <MenuItem value="all">
                      <em>All</em>
                    </MenuItem>
                    {cities.nodes.map(town => {
                      return (
                        <MenuItem
                          key={town.acfDetails.city}
                          value={town.acfDetails.city}
                        >
                          {town.acfDetails.city}
                        </MenuItem>
                      );
                    })}
                  </Field>
                </FormControl>
              </Grid>

              <Grid item xs={12}>
                <Button
                  color="primary"
                  variant="outlined"
                  type="button"
                  fullWidth
                  onClick={submitForm}
                >
                  Search Campgrounds
                </Button>
              </Grid>
            </Grid>
          </Paper>
        </Form>
      )}
    </Formik>

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
I got it to work by using Apollo Clients onCompleted function. No idea why nextjs / react couldnt' do this (well I think I know, setState is asynch) but this seems to work :D

smackfu
Jun 7, 2004

Isn’t the submit button in Formik just supposed to be a button with type “submit”, and no onClick?

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
You can force it to have a onClick by setting it to that one weird thing.

TBH I’m not a fan of Formik and only used it because of a weird tutorial I was following. I would like to strip Formik and MaterialUI out; they both seem too complex for what I need. I know others have suggested React Select, but is there a good way to handle forms in Next/React other than Formik?

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Are there general opinions around mitigating the failure mode of Promise.all([...])? Default behavior is to reject if any input promise rejects, but a richer implementation might make available an array of accept/rejections. I don't think there is a way to get this by wrapping the existing function, but is there an accepted way to go about it?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Newf posted:

Are there general opinions around mitigating the failure mode of Promise.all([...])? Default behavior is to reject if any input promise rejects, but a richer implementation might make available an array of accept/rejections. I don't think there is a way to get this by wrapping the existing function, but is there an accepted way to go about it?

Just use Promise.allSettled([...]) instead? That literally has the exact API you're after.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Jabor posted:

Just use Promise.allSettled([...]) instead? That literally has the exact API you're after.

I don't have time to type 'Settled'.

More seriously, I didn't know this existed, and VSCode isn't popping it on autocomplete. MDN lists its spec as ECMA-262. Node says that it was introduced in 12.9.0.

I'm targeting node 12.16.3, so I assume this should be available.

Any tips on convincing VSCode that it exists?

edit: Adjusting the 'lib' value in my tsconfig to include "ES2020" (bumping from "2019") fixed this. Now to see what it breaks! Thanks Jabor.

Newf fucked around with this message at 16:36 on Mar 4, 2021

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

oh no computer posted:

I've amended the reducer so that it performs a lookup for each incoming user and only appends a user to the store if they aren't already in it, and that's fixed the issue with my users array being 10x too large with duplicated data, but I'm still making 10x as many API requests...

...I think this is it, I've tried console.logging getState().users in the fetchUser action, and users is an empty array every time it runs, meaning that getState().users.find() always returns undefined . How come the array hasn't been populated at the time the action gets called? Is this possibly a lifecycle thing/an async thing?

Take a step back and describe what you want to have happen, and then how you are trying to go about doing it.

Also, make sure you understand async actions (https://redux.js.org/tutorials/fundamentals/part-6-async-logic )

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Empress Brosephine posted:

You can force it to have a onClick by setting it to that one weird thing.
You shouldn't need to do this though? The browser already knows how to trigger a submit event on the parent <form> when someone clicks a submit button.

Empress Brosephine posted:

TBH I’m not a fan of Formik and only used it because of a weird tutorial I was following. I would like to strip Formik and MaterialUI out; they both seem too complex for what I need. I know others have suggested React Select, but is there a good way to handle forms in Next/React other than Formik?
I would recommend trying to get away from the render-prop pattern (passing a callback function as a child to some component). Using the hook functions from Formik instead will make your experience as lot better/less messy. Alternatively, you could look into React-Hook-Form or React-Final-Form. The experience isn't that much different between them though. :shrug:

Regarding custom select dropdowns, React-Select is not the most flexible library, but it's tried and true. Downshift is another popular option worth looking at.

TheFluff
Dec 13, 2006

FRIENDS, LISTEN TO ME
I AM A SEAGULL
OF WEALTH AND TASTE

Newf posted:

Are there general opinions around mitigating the failure mode of Promise.all([...])? Default behavior is to reject if any input promise rejects, but a richer implementation might make available an array of accept/rejections. I don't think there is a way to get this by wrapping the existing function, but is there an accepted way to go about it?

It seems like you got a solution that works for this particular problem, but for any sort of async control flow more involved than the simple parallelism of Promise.all() (and especially if you're working functional style) I can't recommend the unfortunately-named async library enough. async.reflect() is the way to do it there.

Doom Mathematic
Sep 2, 2008

Nolgthorn posted:

Node http is really interesting, it's poorly documented and feels like it isn't very well cared for.

I'm playing around with `http.createServer((req, res) =>` in conjunction with `const req = http.request((res) =>` which to the naked eye looks straight forward enough. You've got a server that deals with an incoming `req` and outgoing `res`, and you've got a request that deals with an outgoing `req` and incoming `res`.

However the context through which these `req` and `res` objects are created causes them to behave differently and have totally different apis.

For one thing, `createServer` waits for a `req` that inherits from `stream.Readable` and a `res` that inherits from `stream.Writable` whereas `request` is generating `req` and `res` objects which inherit from the opposite. But that isn't enough, because half of the methods that are supposed to be available on either of them disappear.

The node documentation explicitly states that these objects are identical, `<http.ClientRequest>` and `<http.ServerResponse>`. But gets murky about what they inherit from, saying that they inherit from `<Stream>` which isn't an actual thing. You've got four different types of `Stream` there's no singular `Stream` class.

Regardless why aren't the methods intact the documentation says are there? Why am I dealing with this crap api, on a developer tool that's that's completely ubiquitous? It's on version 15 now.

When you do http.createServer((req, res) => ...), the callback (req, res) => ... is a listener for a 'request' event, in which req is an instance of http.IncomingMessage, and res is an instance of http.ServerResponse.

When you do const req = http.request((res) => ...), req is an instance of http.ClientRequest and (res) => ... is a listener for a 'response' event, in which res is an instance of http.IncomingMessage.

I'll give you that http.ClientRequest and http.ServerResponse reportedly extend <Stream>. That's stupid and uninformative. Someone should fix it.

Chas McGill
Oct 29, 2010

loves Fat Philippe
Running into rerender nonsense with contexts that have become too large/interdependent. Before I reach for redux, are any of the newer state management libraries worth checking out? Performance is probably the main aim.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Chas McGill posted:

Running into rerender nonsense with contexts that have become too large/interdependent. Before I reach for redux, are any of the newer state management libraries worth checking out? Performance is probably the main aim.

Before ripping up everything to switch to a state management library, you might want to try this useContextSelector hook library that lets you use contexts with selectors to isolate re-renders.

Based on some recent PR's (1, 2) it looks like a similar API might show up as an experimental feature in react soon too.

Ima Computer fucked around with this message at 00:56 on Mar 5, 2021

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

TheFluff posted:

It seems like you got a solution that works for this particular problem, but for any sort of async control flow more involved than the simple parallelism of Promise.all() (and especially if you're working functional style) I can't recommend the unfortunately-named async library enough. async.reflect() is the way to do it there.

That seems pretty rad, and like it does precisely what I've spent considerable time implementing in a few different places. Thanks.

Chas McGill
Oct 29, 2010

loves Fat Philippe

fireraiser posted:

Before ripping up everything to switch to a state management library, you might want to try this useContextSelector hook library that lets you use contexts with selectors to isolate re-renders.

Based on some recent PR's (1, 2) it looks like a similar API might show up as an experimental feature in react soon too.

Oh interesting, I'll check it out.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Is there anything to consider or that stops me from putting independent pages/functionality into a single Node.JS app? I'm just asking, because I'm not too fond of their way of littering my project folder with 350MB worth of dependencies across 30000 files for a template that does Hello World (e.g. npx create-react-app). So I'd like to minimize that footprint.

MrMoo
Sep 14, 2000

Like a heathen I just symlink node_modules across projects to cut on disk space, :lol:

go play outside Skyler
Nov 7, 2005


MrMoo posted:

Like a heathen I just symlink node_modules across projects to cut on disk space, :lol:

that sounds like a terrible idea

smackfu
Jun 7, 2004

Didn’t yarn try to do that? Haven’t heard much lately but we don’t use yarn at work.

TheFluff
Dec 13, 2006

FRIENDS, LISTEN TO ME
I AM A SEAGULL
OF WEALTH AND TASTE

smackfu posted:

Didn’t yarn try to do that? Haven’t heard much lately but we don’t use yarn at work.

Yarn 2's take on it is basically to put each package in a zip archive and gently caress with node's module resolving (patching require() basically) so things look like they're just working normally. This doesn't actually solve any of the fundamental problems with the javascript ecosystem at all (there is no standard library and everything is optimized for shipping in a browser, which means a gazillion tiny packages), but it does make installs faster at the expense of adding even more insane complexity to the tooling on every level. It's extremely on-brand for javascript, is what I'm saying.

TheFluff fucked around with this message at 01:18 on Mar 7, 2021

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Hey friendly Goons! :)

Is there a reason why NextJS Routing would work on Desktop but not Mobile? On my siteI’ve been working/struggling on the routing works on a desktop but once you try it on a phone it doesn’t work (or at least on a Android running Chrome).

Here is the little siteso far:

https://campground-search-final.vercel.app/

On that front page, the router works on desktop but the same page doesn’t on mobile :(

Wondering if anyone has any clues / ideas about what’s wrong. Here’s my code for that search box:

code:

import Nav from "../components/nav";
import Router, { useRouter } from "next/router";
import {useState} from 'react';

export default function SimpleSearch({ cities }) {
  const router = useRouter();
  const { query } = router;

  const [city, setSelect] = useState('All');

  const handleChange = (e) => {
      setSelect(e.target.value)
  }

  const handleSubmit = () => {
    Router.push(
      {
        pathname: "/camps",
        query: {city, page: 1 },
      })
  };

  return (
    <section
      className="hero is-info is-fullheight"
      style={{
        backgroundImage: "url('/cover2.jpg')",
        backgroundSize: "cover",
      }}
    >
      <div className="hero-head">
        <Nav />
      </div>
      <div className="hero-body">
        <div className="container has-text-centered">
          <p className="title has-text-info is-size-1 has-text-weight-light">
            Where is your next adventure?
          </p>
          <div className="columns is-centered">
            <div className="column is-3">
              <form onSubmit={handleSubmit}>
                <div className="field has-addons">
                  <div className="control is-expanded">
                    <div className="select is-fullwidth">
                      <select className="input is-rounded" name="city" onChange={handleChange}>
                        <option value="all">All</option>
                        {cities.nodes.map((town) => {
                          return (
                            <option
                              key={town.acfDetails.city}
                              value={town.acfDetails.city}
                            >
                              {town.acfDetails.city}
                            </option>
                          );
                        })}
                      </select>
                    </div>
                  </div>
                  <div className="control">
                    <button
                      type="submit"
                      className="button is-info"
                    >
                      Bon Voyage
                    </button>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
So, anyhow, about my earlier question, if I were to put independent React pages/JS into subdirectories, that'd just work like that?

TheFluff posted:

there is no standard library
That is something I don't understand. Trying to do various string and date formatting things, that I take for granted in .NET, Java and even goddamn C, just aren't there. Well, some of it, is. But only from certain versions of the standard onwards. It seems like things are reactionary at best? Like adding String.padStart, after those left-pad histrionics.

Impotence
Nov 8, 2010
Lipstick Apathy

Combat Pretzel posted:

So, anyhow, about my earlier question, if I were to put independent React pages/JS into subdirectories, that'd just work like that?

I wouldn't really call them react pages, they're just bog standard files. Your imports are more or less `import "node-modulename"` or `import "../path/to/file.js"` (or .jsx, or .js, or .vue, or omit the extension, etc.)

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I've already told our product team we're not going to do this in a million years, but does anyone have experience taking a screenshot with JavaScript (which includes stuff in the DOM that's out of the viewport)?

The couple things I looked into either had terrible browser support or were just experimental

MrMoo
Sep 14, 2000

With a user prompt you can use getUserMedia to get a stream of the page and then snapshot a frame from that.

Basically native screenshot support was dropped due to privacy, Google themselves used a horrid version of html2image which has a giant list of unsupported content.

Sergeant Rock
Apr 28, 2002

"... call the expert at kissing and stuff..."
Please don't use markup that is just a massive stack of nested <div>s.

MrMoo
Sep 14, 2000

A lot of popular sites love their divs, I found a new contender to the crown though. Probably due to the animation, I hope it is programmatically generated.

https://www.seenspire.com/product/overview

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Digital signage and the “applications” they use are the loving worst. Plus they’re way overpriced.

MrMoo
Sep 14, 2000

$10/screen/mo isn’t too crazy, but the quality is generally abysmal. Industry is just shy of 2,000 vendors with almost nothing to distinguish between them.

My signage “applications” are clearly awesome though 😎

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
What's the best way to deal with grids (in React)? Just use a plain HTML table, or is there a preferred control? I'm looking for something that works kind of like WPF's Grid, i.e. specifying grid and row columns and then place the controls with row, column and appropriate span attributes.

Adbot
ADBOT LOVES YOU

barkbell
Apr 14, 2006

woof
css grid

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