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
fuf
Sep 12, 2004

haha
Is the official angular "phonecat" tutorial out of date / broken?

Step one is to launch the node web server in angular-phonecat/scripts/web-server.js, but the file doesn't exist:

https://github.com/angular/angular-phonecat/tree/master/scripts

Any other good angular tutorials someone can recommend? (bonus points for angular + node)

This is the best one I've done so far, but it doesn't get into much detail:

http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular

Adbot
ADBOT LOVES YOU

fuf
Sep 12, 2004

haha

oh dang that's a lot. Thanks.

I've been learning the MEN bit of MEAN for a while, but I never really understood what angular (et al) were for. Then I realised I was writing a lot of messy jquery to update html elements without refreshing the page, and something finally clicked.

fuf
Sep 12, 2004

haha

Spraynard Kruger posted:

I think said web-server.js is installed via an npm package, did you run npm install?

Aha, you are kind of right. There's still no web-server.js where the tutorial says there should be, but I checked package.json and 'http-server' is in the dependencies (and can be launched with 'npm start').

In the end though I started working through this guide instead and so far it's pretty good:
http://www.thinkster.io/angularjs/GtaQ0oMGIl/a-better-way-to-learn-angularjs

fuf
Sep 12, 2004

haha

darkgray posted:

There are problems cropping up, though. For one, AngularJS will reload the route's controller every time you request a page, and this means the browser has to tear down the entire DOM of 5000 nodes or whatever, and rebuild it again with the new data.

You might also want to look into https://github.com/angular-ui/ui-router

It lets you nest views so you can update an inner view (and the url) without reloading the outer view. Here's a demo:

http://plnkr.co/edit/u18KQc?p=preview

fuf
Sep 12, 2004

haha
Where do people put their Angular (or whatever) template files?

They have to be accessible from the web right? Currently my project is laid out like this:

code:
- public/
-- css/
-- js/
-- img/
-- templates/
--- home.html
--- about.html
-- index.html
But it bothers me that in theory someone could access site.com/templates/home.html directly and get a broken, non-css version of a section of the site. Is there any alternative? Also does google crawl those files?

fuf
Sep 12, 2004

haha

caiman posted:

I make primarily non-database driven websites. Would learning Angular benefit me at all?

Maybe, it's pretty cool. I use it for dynamically loading content instead of the old mess of jquery ajax methods I used to use. You can use ngRoute to associate a url with a template file that'll load into the main view section of your page. So the url changes between views and the back button works, but you don't have to refresh the page.
(the only issue is that urls look like site.com/#/news instead of site.com/news)

You can also use angular to add "active" classes to nav links etc. Basically a lot of stuff I use to use jquery for I now do in a much cleaner / neater way with angular (except animations, because that poo poo confuses the hell out of me).

fuf
Sep 12, 2004

haha
I'm finding it hard to find a good balance between easing load on the server and sending unnecessary data to the client.

My app lets users search a list of ~1000 book titles. I don't know whether it would be more efficient to:
a) send the entire list to each client when the page loads and let the front end (Angular in this case) handle all searching and filtering.
b) perform the search on the server and only send the results to the client.

I'm inclining towards option a) because although it means a slower initial page load it should make "live" searching a lot smoother. But something in me balks at the idea of sending all that data to the client (especially if the db starts getting bigger...).

Any thoughts? How do other people make these kinds of decisions?

fuf
Sep 12, 2004

haha

Subjunctive posted:

1000 book titles is going to be like 30K of data before compression, and it can be loaded in parallel with the rest of the page to not block long. You could keep it prepared and compressed so it's a static load and basically zero server impact.

OK when you put it like that the answer seems obvious! Makes life a lot easier as well if I only need one call to the back end. Also I guess in the big scheme of things bandwidth is cheaper than processing power?

Thanks for the input - just wanted some reassurance I wasn't missing something :)

fuf
Sep 12, 2004

haha

The Merkinman posted:

So I'm starting a new project from scratch using Foundation and SASS. Should my entire site be in app.css? That seems a bit bulky to have CSS for elements on one page loaded on all pages. Is a suggestion way to have app.css really just be for elements like .columns, <p>, <h1>, and not .myWidgetContainer, #thingOnOnlyOnePage etc?

If you're already loading the whole of Foundation on every page then I don't think a few of your own css rules are going to make much difference.

You could also look into the frameworks mentioned in the OP of this thread that let you load content without refreshing the page - that way you only need to load your css once.

A good way to trim down your css is to check foundation.scss and comment out any components that you know for sure aren't being used. I have a single "main.scss" which imports just the Foundation components I need and then I add my own rules.

fuf
Sep 12, 2004

haha
how come

fuf
Sep 12, 2004

haha
I've been using angular and ngRoute to make very basic static sites. Basically my only logic is a list of routes like:
code:
  .when('/about', { 
       templateUrl: 'templates/about.html'
   }
Basically doing the same thing I used to do with
code:
<?php include 'templates/about.php' ?> 
etc.

Is there another JS framework that is good for this kind of thing? Maybe a little more lightweight? I want to try something other than angular.

e: I guess backbone with LayoutManager?

e2: actually ember looks a lil easier

fuf fucked around with this message at 14:13 on Sep 4, 2014

fuf
Sep 12, 2004

haha
I'm actually kinda enjoying ember so far.

But I just got stuck trying to conditionally add a css class (<header> has class "fullpage" when url is "/"). Can someone tell me the simplest way to do this or point to the right documentation (surprisingly hard to google)? I optimistically tried to just start using jQuery but I can't 'select' anything except <body> for some reason:

code:
App.IndexRoute = Ember.Route.extend({
   activate: function(){
      console.log("this is the home page lol"); // works
      $('body').addClass('fullpage'); // works
      $('header').addClass('fullpage'); // doesn't work 
   }
});

fuf
Sep 12, 2004

haha
Couldn't find anything on didInsertView but I think you meant didInsertElement - and that works! Thanks :)

fuf
Sep 12, 2004

haha

Maluco Marinero posted:

For anyone who just wants to ajaxify a more simple website to behave like a single page app try http://sennajs.com , I haven't used it but looking at the API it seems more geared towards that use case.

I tried this today but it's not quite what I was expecting. It really is for converting existing static sites, because each page needs to be a full html page with its own <head> and nav menus etc etc.

Really I want something that loads page snippets into my main index.html, and which also allows for routing so people can hit me.com/about etc. and get the right page. Anything lightweight that does that or should I stick with ember?

fuf
Sep 12, 2004

haha

Lumpy posted:

Check out React and react-router.

I'd looked at React in the past and just had a look at react-router.

The thing I'm not sure about is React components only ever seem to have really small html snippets defined right there in the app code, like this:

code:
var Header = React.createClass({
  render: function() {
    return (
      <header>
        <ul>
          <li><a href="/">Dashboard</a></li>
          <li><a href="/inbox">Inbox</a></li>
          <li><a href="/calendar">Calendar</a></li>
        </ul>
        Logged in as Joe
      </header>
    );
  }
});
But I can't really do this for a full page's worth of content with paragraphs and images etc. Is there a method which uses external html files like with Angular's TemplateUrl?

fuf
Sep 12, 2004

haha

Maluco Marinero posted:

but tbqh you may get along just fine with a combination of 'flatiron director' for your routing and jQuery for getting snippets and injecting them. You barely need any front end framework if that's all you're doing, but I'm saying that with no knowledge of exactly what you're doing.

Yeah this is probably what I should do. I've been trying to use various frameworks just as a learning experience, and so that I can say I've used them. But actually most of the sites I end up making at the moment are just old-school static pages. Maybe I'm being counter-productive and should wait until I need to make something more app-like.

Or maybe using that flatiron director router would be a good compromise.


Subjunctive posted:

I don't know of an existing component that wraps XHR and dangerouslySetInnerHTML (other than <iframe> :v:), but DIY wouldn't be too hard. Keep the currently-loaded content in state, trigger a load of it on nav, and in render jam it in. The tutorial does this with the markdown comments, IIRC.

Thanks, I'll keep this in mind. :)

fuf
Sep 12, 2004

haha

Pollyanna posted:

I'd love to learn a bit more about how front-end MVC frameworks work, but I have trouble learning the basics in a Javascript context. Is there some sort of MVC framework that uses similar concepts (like two-way binding, events, controllers, etc.) in a language like Ruby or Python? I'm just mentally allergic to Javascript.

You're confused about something... Ruby and Python are server-side languages, so obviously there's no front-end (client-side) frameworks built with them. If you just mean MVC in general then there's Ruby on Rails and Django.

e:

Pollyanna posted:

But I still don't quite get what all this poo poo does in a Backbone application, or why I need all of it:

So you're asking how Backbone works?
http://backbonetutorials.com/

fuf fucked around with this message at 17:03 on Oct 3, 2014

fuf
Sep 12, 2004

haha
Does anyone know of a javascript library that will resize a bunch of elements so they fit into a container without any scrolling?

I think I need to be googling something like masonry/mosaic/grid/tile/wall, but I can't find anything that does exactly what I want.

All the ones I've found you have to specify a number of columns, but I want something that will just fit elements into the available space (with roughly the same number of rows and columns).

I'm using React.

fuf fucked around with this message at 14:24 on Sep 17, 2022

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?

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)

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.

fuf
Sep 12, 2004

haha
I still haven't really got my head around the best way to mix server and client components in NextJS. Specifically how to update data with prisma in response to client actions.

Here's a simple component that I've written as if client and server actions can magically coexist, to show what my goal is:

JavaScript code:
export default async function UpdateSlotCategory({ slot }: { slot: Slot }) {
  const categories = await prisma.category.findMany();

  const handleChange = async (categoryId: string) => {
    await prisma.slot.update({
      where: {
        id: slot.id,
      },
      data: {
        category: {
          connect: {
            id: categoryId,
          },
        },
      },
    });
  };

  return (
    <div className="w-48">
      <p>Change Slot Category</p>
      <Select onValueChange={handleChange}>
        <SelectTrigger>
          <SelectValue placeholder="Select a category" />
        </SelectTrigger>
        <SelectContent>
          {categories.map((category) => {
            return (
              <SelectItem key={category.id} value={category.id}>
                {category.name}
              </SelectItem>
            );
          })}
        </SelectContent>
      </Select>
    </div>
  );
}
Obviously it doesn't work because the prisma actions and the onValueChange event can't be part of the same component.

How would you guys break this down in the simplest way? Ideally with the least number of additional files / components. I think I can see various ways but they all seem overly complicated and I'm not sure if there's a standard easy way.

fuf
Sep 12, 2004

haha

hey mom its 420 posted:

I think that should work actually, you just have to put a 'use server' directive inside the handleChange function. client components can get passed server actions as props no problem.

Oh wow, uhh yeah that worked. That's pretty amazing, thank you.

For some reason I thought if I had "use server" at the top of the file then putting "use server" on functions within the component wouldn't make any difference.

fuf
Sep 12, 2004

haha
Here's another NextJS question that I'm hoping I might be overthinking and might have a simple answer:

Say I have a /category/[categoryId]/ route that lists all the posts in a category.

But I also want a search filter on this page which persists per category page.

So on page /category/1/ I can set the search text to "foo", on /category/2/ to "bar", and then navigating back to /category/1/ will switch the search text back to "foo".

I know you can store stuff in the URL using searchParams but I'm not sure how this would work for navigating between multiple categories each with their own search text - maybe they can all be stored in the URL at the same time but that seems like a lot.

I think I could use a global state manager like Zustand and create a store of "CategorySearchFilter" objects.

But is there an easier way? Basically a kind of per-page persistent state?

Adbot
ADBOT LOVES YOU

fuf
Sep 12, 2004

haha

hey mom its 420 posted:

What would you expect to happen when you just F5 the page? My guess would be for them to remain there, right? If so, then I think your choices are either storing them in the URL (might make it kind of long, but probably your best bet), cookies or local storage. If you go for local storage or cookies, you have to assign each page some kind of key (you'll probably be using categoryId) and then create a mapping from keys to filters.

Thanks. I actually don't really mind if F5 wipes everything, which is why something like zustand might be an option.

The thing I don't get about using the URL is how to persist the same searchParams object across all the different routes.

I did have something that was using the URL to filter by tag ID that looked like this:
JavaScript code:
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();

const handleToggle = async () => {
    const params = new URLSearchParams(searchParams);
    const tagId = tag.id;
    (searchParams.get("filter") === tagId) ? params.delete("filter") : params.set("filter", tagId);
    router.push(`${pathname}?${params.toString()}`);
}
And then I could get the filter in the /category/[categoryId] page like this:
JavaScript code:
export default async function Page({
  params,
  searchParams,
}: {
  params: { categoryId: string };
  searchParams: { [key: string]: string | undefined };
})
But what about all the other routes the user might hit in between toggling the tag filter and returning to the category page? /post/123/, /settings/, etc. etc.

At the moment I'm linking to routes all over the place using <Link>, like this:
JavaScript code:
<Link href={`/category/${category.id}/presets`}>
   <div>{category.name} presets</div>
</Link>
I think I would need to update everywhere I use <Link> to somehow append the searchParams object each time?

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