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
Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Full Circle posted:

Haven't used any of those libraries in ages, but do you just need an event.preventdefault() in the @action?

When you use an event handler with the {{on}} helper, you get the event as the first argument. That's why I use the {{fn}} helper there to decorate the call with information about which field should be set.
If you do <input {{on 'input' this.handleInput}}>, your event handler signature is handleInput(event).
If you do <input {{on 'input' (fn this.handleInput 'someField')}}>, your event handler signature is handleInput(fieldName, event), where fieldName would be 'someField' in this case.

Ima Computer posted:

As long as your markup creates the right association between a label and an input (which yours does) clicks on the <label> don't need to be handled - only the input. Redirecting events to the target input is one of the primary features of <label> tags.

Yeah, I think I did something dumb (months) earlier and somehow added an even number of event handlers and then accidentally got it working with my triple invocation.

Adbot
ADBOT LOVES YOU

Ihmemies
Oct 6, 2012

We are doing a project for university's database course. We were given the spec of a billing system web app, and an option to use either PHP or node.js. Database must be postgres.

So that mainly leaves the frontend questions open. Since none of use are very eager to do frontend stuff in our team, someone suggested using HTMX. Basically that adds a bunch of features on top of html you can use to update the content of your webpage: https://htmx.org

I think that leaves us to how to make the page look a bit more modern than what CERN had in 1995, without writing css too manually. Maybe tailwind CSS? https://tailwindcss.com With tailwind we could do also the styling in HTML.

So my question is, does that make sense? Postgres with node.js and express? HTMX+Tailwind CSS in frontend? The course chiefly concentrates on database design and implementation, the app is just there for us to prove that we can implement something which works and meets the specification.

hey mom its 420
May 12, 2007

Tailwind is super good and cool to use. You basically can't go wrong with that. HTMX is fine for that too.

as the resident next.js enjoyer here I have to recommend it for your use case I guess. It's pretty much a server-first framework now, and if you use server actions, you don't have to mess about with REST, serialization/deserialization, endpoints and templates and you can just focus on the DB part (I recommend drizzle!). you just do the fetching in the components/pages and link forms to JS functions that update your db. it also gives you typescript through the whole stack so it's much easier to work with as a team. it's also easy to deploy on vercel or whatever and since it's a university thing, the free tier will be more than enough.

Ihmemies
Oct 6, 2012

Does that mean we would then use postgres with node.js, next.js?

I am not sure if next.js replaces express completely or partially in a case like this, and do we need a separate thing like tailwind to ease the styling of frontend still?

Obfuscation
Jan 1, 2008
Good luck to you, I know you believe in hell
Tailwind is certainly fine but if you want to put the least amount of effort into css and still have something that looks good I'd use some CSS library that comes with premade components, like Bootstrap or Fomantic UI

hey mom its 420
May 12, 2007

Next.js runs on node.js. It's like running Django on Python. And you just call access your DB from your next.js components and actions.

As for premade components, I like the copy and paste libraries for tailwindCSS like DaisyUI or Flowbite. you don't install the component libraries, but you just copy and paste the components from their websites and that's it.

prom candy
Dec 16, 2005

Only I may dance
If you don't like front end stuff don't use NextJS. Your plan of PHP and HTMX sounds fine. Consider using Laravel if allowed. DaisyUI is a nice UI library that's built on top of Tailwind.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
I'm trying to find out why our webapp goes haywire in certain situations. I have 2 problems:

The profilers in both firefox and chrome are not exactly intuitive, but that's a skill issue. But is there a way to highlight or filter only our own code? The compiled app has 2 script files: assets/vendor-[content hash].js (the framework and libraries), and assets/appName-[content hash].js (our own app code). I'm mainly interested if the app spends a lot of time in our own code, in the appName file.

The bigger problem is that when I manage to trigger the thing that causes the infinite loop, both the web page and developer tools become unresponsive. I'm unable to capture the profile and I'm unable to analyze it. I'm also unable to pause the execution.

Haystack
Jan 23, 2005





Do your complied .js files have associated .map files? Eg, something like assets/appName-[content hash].js.map. Map files let you source code in the debugger for compiled file, as if it weren't compiled, letting you set breakpoints, loggers, etc.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Wheany posted:

When you use an event handler with the {{on}} helper, you get the event as the first argument. That's why I use the {{fn}} helper there to decorate the call with information about which field should be set.
If you do <input {{on 'input' this.handleInput}}>, your event handler signature is handleInput(event).
If you do <input {{on 'input' (fn this.handleInput 'someField')}}>, your event handler signature is handleInput(fieldName, event), where fieldName would be 'someField' in this case.

Yeah, I think I did something dumb (months) earlier and somehow added an even number of event handlers and then accidentally got it working with my triple invocation.

I think I figured it out. I have some some radio buttons that are inside a bootstrap <div data-toggle="buttons"> element. Like so:
HTML code:
<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-default {{unless this.displayAll 'active'}}">
        <input type="radio" name="displayAll" value="false" checked={{unless this.displayAll true}}/>
    </label>
    <label class="btn btn-default {{if this.displayAll 'active'}}">
        <input type="radio" name="displayAll" value="true" checked={{this.displayAll}}/>
    </label>
</div>
Bootstrap uses a click handler on the labels to toggle the "active" state on them and it also calls preventDefault on the event, which causes the {{on 'input'}} handler on the radio buttons (left out of the above snippet) to not be called. So I probably just started to copy-paste the working solution from this specific place to everywhere else

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice
I am making a small static site for some nerdy hobby stuff I do, and I used Astro, and it's pretty great for that.

Lumpy fucked around with this message at 01:37 on Feb 15, 2024

prom candy
Dec 16, 2005

Only I may dance

Lumpy posted:

I am making a small static site for some nerdy hobby stuff I do, and I recalled someone liking Astro, so I gave it a whirl, and it's pretty great for that. So thanks to whoever mentioned it!

You were the first person to mention Astro in this thread lol

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

prom candy posted:

You were the first person to mention Astro in this thread lol

My deepest apologies. I will edit my post to reflect that.

Insanite
Aug 30, 2005

I'm building a new portfolio with Astro. Hoping it's not overly complicated for basically a glorified brochure, but it doesn't seem bad at all.

prom candy
Dec 16, 2005

Only I may dance

Lumpy posted:

My deepest apologies. I will edit my post to reflect that.

I think it's possible that I mentioned it before you in one of the other threads, there's a lot of overlap between a few of these

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
I'm building an application with the latest fanciest buzzwords available right now. Server components that render immediately, html hydration, server actions triggered by client side state, and *drools*.

However I've run into a bit of a snag now that the honeymoon is wearing off. It turns out not having a server that I'm building and instead relying on the library I'm using to write one for me, has a limiting factor. Which is that I'm at the stage of development where I need to implement real time communication.

Websockets, so I'm told, are inherently not compatible with whatever is going on in the background of modern technologies. It is recommended, from everything I've read so far, to build a secondary traditional icky service that deals with websockets.

Which means I'm going to need my fancy app to communicate with it, so that it can communicate with my users. This is probably doable and workable. But what is the best method of communicating with it?

It's essentially a microservice. Should I just send it post requests?

MrMoo
Sep 14, 2000

You can probably just use SSE and a basic GET query. Send a basic notification over SSE that gets the client to query for updated state and do what it needs to do.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
I'm less familiar with server sent events, in fact I've never used them before nor heard of them. However from my understanding it is what I need, for the server to be able to notify the client something changed. Does nextjs 14 support this? I'm not finding very much information about it.

I'll keep reading though thanks for giving me a heads up.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
Ah this is clever. I can easily implement sse, since it's just a regular http2 endpoint. Feels old-school, I like it.

Wondering if it's a big deal for every user of my website to have an open connection with my server that never closes. Doesn't that use up a lot of resources? Please forgive my ignorance, I understand the mechanism it's just surprising since it feels like misuse. I always understood http connections as being something you want to close as early as possible.

MrMoo
Sep 14, 2000

If it is over HTTP/2 or HTTP/3, it is "free", because they duplex everything over a single connection.

If it is over HTTP/1.1 you are limited to 6 connections per DNS name before you get locked out. So with multiple tabs that could happen quickly. Yay for lovely corporate environments. You would have to use the "Broadcast Channel API" to get all the tabs & windows to communicate and elect only one to maintain the connection. I'm sure that is fun. A lot of apps should do that anyway to help force logout.

Alternatively just poll every 10-15 seconds only on the active tab.

MrMoo fucked around with this message at 02:22 on Feb 19, 2024

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
I've been dabbling in Nextjs 14 and got to the point where I needed state management. I wrote off redux before I even started, and landed on zustand. This worked well and I was happy with it until I needed to hydrate from the server, it's not really designed for that. So I switched to jotai, which I like maybe for different reasons, the big benefit it allows me to hydrate during page rendering.

This is not the solution I need though since you can only hydrate an atom once. I had multiple places in the dom adding information to atoms. So... it's also not really designed for what I think I was looking for. Then I thought okay I'll get all the data I need across the page, all at once in one place depending on the url. But that isn't possible either, since nextjs 14 "intentionally doesn't reveal that information to you".

So I'm left with "redisgn what you're doing dummy make less use of state management, or duplicate data in places". Seems like there's a bit of a hole in the market for state management that works on both the server and client, due to all this server components stuff.

Nolgthorn fucked around with this message at 14:54 on Feb 28, 2024

prom candy
Dec 16, 2005

Only I may dance
What do you need state management for? I haven't used any of those libraries in quite a while.

Cheston
Jul 17, 2012

(he's got a good thing going)
I quit my (mid-level front-end) job last year to deal with medical issues, and I'm starting my job search again. Does anyone have recommendations for front-end interview prep?

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Nolgthorn posted:

So I'm left with "redisgn what you're doing dummy make less use of state management, or duplicate data in places". Seems like there's a bit of a hole in the market for state management that works on both the server and client, due to all this server components stuff.

It's not entirely clear what you're trying to do and what problems you're having, but if you're trying to synchronize state/data between your server and client, the solution you're looking for is probably TanStack Query

Client-side state management libraries (Redux/Jotai/Zustand/et al) are not meant to manage state on the server, that's what databases are for.

camoseven
Dec 30, 2005

RODOLPHONE RINGIN'

Cheston posted:

I quit my (mid-level front-end) job last year to deal with medical issues, and I'm starting my job search again. Does anyone have recommendations for front-end interview prep?

The job market is a loving shambles right now and you're going to be lucky to get any actual tech interviews. Make sure your resume will pass a keyword scan for any job you apply for. Work on your answers to questions that moron HR screeners ask like:

A brief overview of your resume/career
Most impressive thing you've built
Interpersonal scenarios (times you disagreed with a coworker or whatever)

And then if you actually ever get through to a tech screen you can worry about those questions based on the tech stack they use, though by far the most common tech question I get is "if you were to build a greenfield app what would your tech stack be" which is a dumbass loving question because whenever I follow up with "well what are the business requirements, what's the app supposed to do, what do people at the job already know" they say poo poo like "doesn't matter assume you don't know that stuff". gently caress YOU. gently caress.

Sorry I'm really loving burnt out by horseshit hiring practices. Do us all a solid and if you get any one way video recorded interview requests decline that poo poo.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense

Ima Computer posted:

It's not entirely clear what you're trying to do and what problems you're having, but if you're trying to synchronize state/data between your server and client, the solution you're looking for is probably TanStack Query

Client-side state management libraries (Redux/Jotai/Zustand/et al) are not meant to manage state on the server, that's what databases are for.

Sure.

So with all the fancy new stuff coming out of Vercel we have Server Components and Client Components. Client components is the React we all know so well and Server Components are the new dominant fun thing that should comprise the majority of any new application. The server renders both Server and Client components on page load, delivers it all to the client as html and then React hydrates it. This is that hairy business nobody liked because it was a bloated mess that never really worked for years and required tons of boilerplate and nonsense to try to run in the first place.

Today it's pretty much cleaned up and how things are done now in the world I'm playing in. So the problem is, that when the application is rendering all your Server and Client components, and you expect your client components to have some degree of reactivity, you are using state of some kind in those Client Components. You don't get the benefit of the server rendering everything if that state doesn't exist while the server is rendering it.

Therefore the golden goose is that you can populate the store on the server, so that those client components have something to render, and have it show up on the client after everything gets there.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
For anyone who's interested this is how I got it working p. smooth with jotai.

JavaScript code:
export default async function RootLayout() {
    const hydrate = await getHydrationData();

    return (
        <Provider>
            <AppInitializer hydrate={hydrate}>
                <html lang="en">
                [...etc]
JavaScript code:
"use client";
export function AppInitializer({
    hydrate,
    children,
}: AppInitializerProps) {
    // hydrate the store with whatever data here
    useHydrateAtoms([
        [userAtom, hydrate.session.user],
        [profileAtom, hydrate.session.profile],
        [profilesMapAtom, add({}, ...hydrate.profiles)],
        [chatsMapAtom, add({}, ...hydrate.chats)],
    ]);

    return children;
}
And then it works. I was trying to do this in multiple places when really what I needed to do was fetch all of that data for those pages on demand like so.

JavaScript code:
export default async function HomePage() {
    async function getMorePosts(before: number) {
        "use server";
        return await getHomePagePosts(before, POSTS_PER_PAGE);
    };

    const initialData = await getHomePagePosts(Date.now(), POSTS_PER_PAGE);

    return (<>
        <FiltersBar />
        <ContentWrapper isLoading={false}>
            <InfinitePosts initialData={initialData} getMorePosts={getMorePosts} />
        </ContentWrapper>
    </>);
}
JavaScript code:
"use client";
export default function InfinitePosts({
    initialData,
    getMorePosts,
}: InfinitePostsProps) {
    const [posts, setPosts] = useState(initialData.posts);
    const [profiles, setProfiles] = useState(initialData.profiles);
    [etc...]
I was stuck in my head about client components when really server components can do a lot and I don't really need a full blown store so much for these areas. Just the common stuff around the site rather than in the main content area.

scissorman
Feb 7, 2011
Ramrod XTreme
Not sure if this thread is the right one or if I should post this in web design thread.
Anyway, my question, I'm currently working as a relatively new tech lead for an internal project with 3 additional frontend developers.
We use Angular, Material and NgRx (the enterprise hattrick) and are currently facing problems because the previous developers decided to heavily customize Material to fit the product owner's designs instead of using the Material Design system.
This makes new development and updates painful and our new designer also is rather unhappy, so I'm researching what our options are.

Is customizing Angular Material always a bad idea?
At my previous job we had a UI team do the same but they were a lot better at this than us.
Also they probably didn't try to reach into the components via CSS and Typescript fuckery.

We have the option of using an internal design system with very well done HTML and CSS but missing components and no ready-made Angular wrappers, so that's not an easy solution either.
We might however be able to get good internal support.

Gildiss
Aug 24, 2010

Grimey Drawer
Just wanted to make a quick post about a drat Adobe analytics script injected some jquery that searched for any anchor tags and attached a click event listener that then set the window location to the href value from the a tag, loving up the spa routing.

Took our team almost all day to track down why our site randomly was getting busted when no code deployments happened.

gently caress Adobe poo poo and gently caress analytics.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
Why I often avoid using libraries and modules whenever possible, assuming I have a good team that's the first place I look.

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense
I mean why the hell is a company as big as Adobe importing jquery. This entire industry is polluted with garbage, not that jQuery is bad by itself there are talented developers who recently released a new version but why is it needed? It's insane it's like these companies just hire anybody and they don't care about the product at all. It's wild man it's not congruent with reality.

Just one high quality developer could have looked at that and said "hey lets replace jQuery" and it would have taken one developer like a day or two, maybe? Maximally? But these companies have hundreds of developers. And what are they doing? I have to suspect all of the layoffs are due to just the fact that they hired nonsense to begin with. The software development bubble is dead.

No wonder nobody is hiring anybody except experienced devs at this point. It's been ruined.

fuf
Sep 12, 2004

haha
I've been playing with Prisma in a NextJS app.

It's cool that Prisma creates types for you automatically, but if I do something like this:
JavaScript code:
const post = await prisma.post.findUnique({
    where: {
      id: params.postId,
    },
    include: {
      tags: true,
    },
  });
then typescript complains when I reference post.tags because the Post type created by Prisma doesn't have a "tags" property.

The only thing I can think of is to create loads of random types like
JavaScript code:
type PostWithTags = Post & {
  tags: Tag[];
};
Is there a better, more consistent approach to this problem? Should I maybe not be relying on "include" so much and just get the tags separately?

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

fuf posted:

then typescript complains when I reference post.tags because the Post type created by Prisma doesn't have a "tags" property.
I've only just played around with it briefly, but Prisma should compose the type properly, resulting in post being the exact intersection you've described. What's your schema for the relationship?

fuf
Sep 12, 2004

haha
Schema:

JavaScript code:
model Preset {
  id            String   @id @default(uuid())
  name          String
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt
  category      Category @relation(fields: [categoryId], references: [id])
  categoryId    String
  tags         Tag[]
}

model Tag {
  id        String   @id @default(uuid())
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  category  Category @relation(fields: [categoryId], references: [id])
  categoryId String
  presets  Preset[]
}
After playing around a bit more, it looks like I can actually reference preset.tags in the same component as the prisma call, because like you say prisma is composing the right type based on what I've asked for. The issue comes when I try to pass the preset to a child component and reference its tags in there:
JavaScript code:
 const preset = await prisma.preset.findUnique({
    where: {
      id: params.presetId,
    },
    include: {
      tags: true,
    },
  });

console.log(preset.tags.length) // Works fine

return(
<SinglePreset preset={preset}/>
)
JavaScript code:
import { Preset } from "@prisma/client";
export default async function SinglePreset({ preset }: { preset: Preset }) {
  console.log(preset.tags.length);  // "Property 'tags' does not exist on type"
}
(This might all be symptomatic of a broader issue with how I'm approaching NextJS - I'm getting the data in server components and then passing it to child client components so I can use click events etc. Maybe this is the wrong approach)

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

fuf posted:

After playing around a bit more, it looks like I can actually reference preset.tags in the same component as the prisma call, because like you say prisma is composing the right type based on what I've asked for. The issue comes when I try to pass the preset to a child component and reference its tags in there
Oh, I'd mistaken the question for being about the inferred type of the `post` reference not having the included tags prop, rather than properly typing the components they're being passed to. Yeah, I don't think you have an option other than manually creating these intersection types in a common spot if you want to consume them across your application, but I'd be curious if anyone that actually uses Prisma day-to-day has any tips and tricks.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
has anyone used nanostores and it's surrounding ecosystem of libraries in a SPA framework and have opinions on it?

https://github.com/nanostores/nanostores
https://github.com/nanostores/query

N.Z.'s Champion
Jun 8, 2003

Yam Slacker

fuf posted:

I can actually reference preset.tags in the same component as the prisma call, because like you say prisma is composing the right type based on what I've asked for. The issue comes when I try to pass the preset to a child component and reference its tags in there:

I put some Prisma calls individually in functions and then use the TS helper ReturnType and Awaited to extract the Prisma type and keep it in sync with the query.

TypeScript code:
export async function findUniquePresetIncludeTags(presetId: string) {
  return prisma.preset.findUnique({
    where: {
      id: presetId,
    },
    include: {
      tags: true,
    },
  });
}

type PresetWithTags = Awaited<ReturnType<typeof findUniquePresetIncludeTags>>


export default function SinglePreset({ preset }: { preset: PresetWithTags }) {
  console.log(preset.tags.length);
}

N.Z.'s Champion fucked around with this message at 12:07 on Mar 11, 2024

Adbot
ADBOT LOVES YOU

fuf
Sep 12, 2004

haha

N.Z.'s Champion posted:

I put some Prisma calls individually in functions and then use the TS helper ReturnType and Awaited to extract the Prisma type and keep it in sync with the query.

drat, I'm new to typescript so this is some next level poo poo. Thanks.

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