|
We could also put some funky types on it. I prefer to return the value from async functions so it would look something likeTypeScript code:
Nolgthorn fucked around with this message at 14:39 on Jan 23, 2024 |
# ? Jan 23, 2024 14:32 |
|
|
# ? May 13, 2024 06:58 |
|
Unless I'm misunderstanding even more , we all seem to be forgetting the metricScope() func from the library, and the fact I'm not explicitly defining the 'metrics' value above any of the code? To reference their docs: TypeScript code:
|
# ? Jan 23, 2024 15:22 |
|
Oh I get it. I misred the code. Dunno what you're working with but assuming it's a callback because it's got a delay you can make it async yourself. TypeScript code:
TypeScript code:
|
# ? Jan 23, 2024 15:44 |
|
VagueRant posted:Unless I'm misunderstanding even more , we all seem to be forgetting the metricScope() func from the library, and the fact I'm not explicitly defining the 'metrics' value above any of the code? quote:Unless I'm misunderstanding even more , we all seem to be forgetting the metricScope() func from the library, and the fact I'm not explicitly defining the 'metrics' value above any of the code? `metrics` is not a variable, it's an argument to a function. `metricScope` takes a function as its argument and `metrics` is the argument of that function. Here comes the "this sounds like scolding but it's actually meant to make you more effective at asking for help in the future": if aws-embedded-metrics has types in its documentation, you should read them; if you want people in a forum to pay attention to the specifics of a library, you should 1. read the docs yourself 2. indicate in your post that you read them and what you didn't understand 3. post a link to the docs, like this one. Because I'm an idiot, I'm going to guess how all this works before I read the docs, which are here. Now, here's your free help. TypeScript code:
- the type of `metrics` is actually `MetricsLogger` - `metricScope` is a decorator function to which you pass a function that expects a `MetricsLogger` and returns any async function; as a decorator, it wraps the inner function so that it has a freshly created `MetricsLogger` and so that when the inner function is done, the `.flush()` method will be called on that `MetricsLogger`. Basically, `metricScope` looks confusing, but it's there to reduce boilerplate, assuming you have lots of little chunks of code that need to get a MetricsLogger. If you don't use `metricScope`, you have to remember to get the logger and flush the logger in each one of those chunks of code. TypeScript code:
|
# ? Jan 23, 2024 16:11 |
|
Fully unwrapping the initial code sample, you end up with something like this:TypeScript code:
|
# ? Jan 23, 2024 16:17 |
|
e:dw
echinopsis fucked around with this message at 09:11 on Jan 24, 2024 |
# ? Jan 24, 2024 08:47 |
|
I have a pretty simple React app that I made with create-react-app and want to host somewhere. A lot of the stuff I'm looking at, like https://www.digitalocean.com/products/app-platform, assumes that you want to pull from a github repo and then run the build process on the production server itself, but I'm struggling to see why this is an advantage. If I run "npm run build" locally then what I end up with in the /build folder is just a static site that I can host anywhere, right? It feels easier to just deploy that folder directly to a basic hosting server running nginx, or even a crappy shared hosting package, compared to a server running a node build process. Is it weird / bad to have a second github repo just for the /build directory to push new builds to the hosting server? Do hosting providers get pissed if you host an actual "app" rather than just another generic WordPress site? It's just serving a couple of mb of html, js, and css so I don't see why, but maybe I'm missing something. I saw something about using S3 to server static sites but that seems like overkill for where I'm at. I dunno if there's a middle ground somewhere between S3 and an old school cPanel on a shared host setup?
|
# ? Jan 27, 2024 10:24 |
|
fuf posted:Is it weird / bad to have a second github repo just for the /build directory to push new builds to the hosting server? I did this with a new "build" branch instead and removed /build from .gitignore on this branch. Then I created a new DigitalOcean App and pointed it at the /build directory of the build branch and it successfully detected it as a static site and deployed it. Pretty cool! I haven't used DO for years and I kind of love it. It's like baby's first AWS. It's pretty powerful but generally very straightforward.
|
# ? Jan 27, 2024 11:04 |
You can also just use the gh-pages module to automate the whole thing on github pages from a single repo.
|
|
# ? Jan 27, 2024 11:50 |
|
fuf posted:assumes that you want to pull from a github repo and then run the build process on the production server itself That doesn’t seem right to me? In 2024, I would expect them to build your site into a docker image that would be what is actually the “production server.”
|
# ? Jan 27, 2024 13:19 |
|
Osmosisch posted:You can also just use the gh-pages module to automate the whole thing on github pages from a single repo. Oh yeah, that might save a few steps. Thanks. smackfu posted:That doesn’t seem right to me? In 2024, I would expect them to build your site into a docker image that would be what is actually the “production server.” I'm probably missing a few steps. When you create an App you point it at a repository and it tries to figure out the best way to build and serve it. Maybe it builds a docker image every time I dunno. It seems good but when I point it at my create-react-app repository, it says: To me this looks like it's gonna serve the app by just running "npm start", which doesn't make sense. I want it to serve the contents of /build as a static site... You can probably configure it all but it seems easier to build locally and then let it recognise my new build branch as a static site. (also if it has to do the build then it classifies it as a "web service" and it's billed differently than the static site)
|
# ? Jan 27, 2024 13:57 |
|
I just had coffee so I'm going to write too many words here:fuf posted:A lot of the stuff I'm looking at, like https://www.digitalocean.com/products/app-platform, assumes that you want to pull from a github repo and then run the build process on the production server itself, but I'm struggling to see why this is an advantage. DO App Platform is a Heroku-like. It uses "buildpacks," which are a spec for how to build an application's source into an image that can be deployed somewhere (probably an OCI/Docker image under the hood). Heroku's buildpacks became a spec (https://buildpacks.io/) over the past five or six years and now a few different platforms support it. It's... relatively antiquated, I guess. It made more sense in a pre-Docker world. Now, at the end of the day, it's just generating a Docker image, there's no reason a developer couldn't just write their own Dockerfile instead. But for a single-service project that doesn't use Docker in any other parts of its development process, it can be nice to avoid having the overhead of setting up a Dockerfile and testing it out for production. That said, App Platform also just supports Docker images for builds, which I think is true of most hosted services that support buildpacks in 2024. Now in terms of "why your build runs on App Platform:" generally it is best-practice for production applications to not be built on a developer's local computer. None of the reasons for this are really going to matter for your personal project, but collaborative projects usually have some degree of logging and security around builds and deploys. Plus, you don't want your application to build differently between different developer machines and then have problems in production that can't be replicated easily. I do want to note that the builds do not run in the "production server." There is a separate build environment, because it's gonna output that Docker image, and that's your "production server." BTW, other competitors in this space: Heroku (probably not a good choice in 2024), AWS Elastic Beanstalk (ditto), GCP App Engine (extremely ditto), Azure App Service (not sure anyone has ever used this), Render (actually pretty awesome though I don't expect them to stick around long, someone will buy them). quote:If I run "npm run build" locally then what I end up with in the /build folder is just a static site that I can host anywhere, right? It feels easier to just deploy that folder directly to a basic hosting server running nginx, or even a crappy shared hosting package, compared to a server running a node build process. So, the punchline is that everything I just typed above is kind of irrelevant for your use case because you have a static site. You can absolutely put static sites wherever the hell you want. My personal website is the cheapest DigitalOcean VPS, a Caddy server (re: hipster Nginx), and some files in ~/www that I just scp up there whenever I feel like making changes to it. Now, there are some managed static site hosting solutions that are pretty nice. You've already settled on GitHub Pages from the sound of it and, yeah, you should probably just use that, it's super effective. The fancier managed solutions will get you cloud builds for your static assets (again, not really relevant for a personal project) as well as some fancy vendor-specific tools they'll try to lock you in to keep you from realizing that all they're doing is offering S3 and CloudFront at a 1000% markup. Products in this space include Netlify Core and Vercel Frontend Cloud, which I mention really just because they have pretty generous free tiers (for now). fuf posted:It seems good but when I point it at my create-react-app repository, it says: This is because the buildpack system sees that there's a package.json there and just assumes it is a Node server that it should run; it's not built to just serve static assets. You could stick a static server in there and have it host those files, but that would be pretty silly compared to using a static site host.
|
# ? Jan 27, 2024 19:07 |
|
Thanks for the detailed writeup, much appreciated. I am going to stick with my DO "App" for now, since it's on the free tier and I have a process that works, but I'll move to GitHub pages if this project continues. I have another React project that is using Strapi for its database and API, so suddenly I won't be in static site territory anymore. I guess this is where Docker could come in? I was just going to try and get it working on a DO VPS tbh. I already have Strapi installed on a Droplet so I think adding the React front end which calls it shouldn't be too hard...
|
# ? Jan 28, 2024 09:47 |
|
My adventures in learning React state management continue, and I'm currently rebuilding my card game app in NextJS 14. I like the idea of using routes to manage state, but uhhhh now my app router directory looks like this: Is this kind of thing normal or have I gone completely insane? I probably don't need all of those pages and layouts, but I'm trying to come up with a consistent pattern so I can build out the UI as necessary. I think I could use parallel routes and intercepting routes to make the hierarchy a little less deep, but I'm not sure I need them (yet) and they might just make things more complex. The app is all about selecting cards for different slots, and then doing stuff with the array of currently selected cards. The routes above handle doing the selecting, but it looks like I'm still going to need to use something like Zustand to keep track of my currently selected cards array in a global store. Which is fine but it would be nice if I could do it all within NextJS. The server-side rendering thing feels like a bit of a double edged sword. I really really love that you can just do something like this directly in a component: code:
But it also adds a lot of complexity, like apparently with Zustand you have to initialise the store both on the server and the client somehow. Anyhoo any NextJS thoughts or tips very welcome.
|
# ? Feb 8, 2024 11:41 |
|
fuf posted:Is this kind of thing normal or have I gone completely insane? Probably closer to the "completely insane" side of that spectrum. Why do you want to do all of your state management via routing? From my vantage point, it seems like a comically clunky way to do what you're trying to do.
|
# ? Feb 8, 2024 15:14 |
|
I dunno I just kept reading loads of stuff about how the thing to do in NextJS is put the state in the URL! The last build of the app (React and zustand, then React and preact signals) had a lot of state stuff that was like currentCategoryId, currentCardId, currentFilter, etc. etc. and it seemed like this would be a good alternative to that. The other thing the old app did was retrieve all the cards from the db on page load and then just store them in state as a massive array. Maybe this is fine but it didn't feel great. With the NextJS version I wanted to see if I could just store the currently selected card IDs in client state (using something like zustand because I know I can't do this bit with the url) and then get the rest of the card data from the DB only when required.
|
# ? Feb 8, 2024 16:02 |
|
If you don't need a page for every dynamic route you can use catch-all segments: https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes You can also ditch the static folders (category, preset, , slot and card). Your route would be something like: /<category id>/<preset id>/<slot id>/<card id>
|
# ? Feb 8, 2024 21:05 |
|
fuf posted:I dunno I just kept reading loads of stuff about how the thing to do in NextJS is put the state in the URL! I guess I don't understand why the ergonomics of storing all of your state via routing is preferable over just using zustand. I've never personally heard of anyone suggesting they use Next.js's routes as a replacement for a more conventional state management tool. The theoretical advantage of it would be, I guess, being able to share your instance of an app via a URL? But I'd still prefer using query params. Just doesn't seem like you'd want to leverage routing unless you really want to make distinct pages; doesn't make sense to me to use it to track the state of a game/app.
|
# ? Feb 9, 2024 00:06 |
|
Boosh! posted:If you don't need a page for every dynamic route you can use catch-all segments: https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes Thanks, those catch-all segments look like they could be useful. And yeah adding a static layer in between each dynamic route was definitely overkill. One thing I can't figure out is how to use Next's <Link> component to append to the current route instead of building an entirely new route. Right now I have to do code:
code:
fsif posted:I guess I don't understand why the ergonomics of storing all of your state via routing is preferable over just using zustand. Maybe I've overegged it slightly by calling it state management. Those routes are just to get to the various pages where cards are listed and can be selected. The actual current state of the game (basically which slots are enabled and which cards are selected) is still in zustand. I have a new pattern where all the route pages are server components that do all the data fetching and list the data, and then the individual list items are client components that have access to the client side zustand state. So for example page.tsx in /[categoryId] looks like: JavaScript code:
JavaScript code:
|
# ? Feb 9, 2024 11:18 |
|
Can't you just link to "./{cardId}"?
|
# ? Feb 9, 2024 11:42 |
|
No, it cuts off the last node of the url for some reason. It's very weird:JavaScript code:
|
# ? Feb 9, 2024 12:06 |
|
Ok turns out there is usePathname https://nextjs.org/docs/app/api-reference/functions/use-pathname so I can do this in client components and it works:JavaScript code:
fuf fucked around with this message at 12:38 on Feb 9, 2024 |
# ? Feb 9, 2024 12:30 |
|
fuf posted:No, it cuts off the last node of the url for some reason. It's very weird: I don't get your problem. It seems to be doing exactly what you want it to do?
|
# ? Feb 9, 2024 16:30 |
|
Jabor posted:I don't get your problem. It seems to be doing exactly what you want it to do? Which one? I tried to put a comment explaining the drawback of each. I have a workaround now for server components because you can get all the route sections up to that point in {params}, but it's still weird to me that "." in the href cuts off the last node.
|
# ? Feb 9, 2024 18:52 |
|
If your route ended in a / the ./ would work like you desire. A regular old anchor tag behaves the same way. If you’re on /foo then ./bar links to /bar. If you’re on /foo/ then ./bar links to /foo/bar.
|
# ? Feb 9, 2024 18:57 |
|
I'm pretty sure the only reason this:quote:
Is giving you a 404 is because your routes are currently set up to expect /category/{a}/slots/{b}. So you have options that work if you do have those fixed fragments in between each value, and options that don't work now but will work if you get rid of them. (Or can trivially be made to work by just modifying the link, like make it "./slots/{slotId}") So what's the problem?
|
# ? Feb 9, 2024 23:28 |
|
fuf posted:My adventures in learning React state management continue, and I'm currently rebuilding my card game app in NextJS 14. I've been playing with this stuff too. Regarding the router, I'm finding it to be pretty awesome for keeping pages organized and all the magic it does with layout is wicked. So I'm feeling drawn to defend it. Why do you need so many ids in your url? Assuming they're unique identifiers all you really need is the last one. You could have `/category/categoryId` the same way you could have `/card/cardId`, unless I'm misunderstanding why your url is so complicated. Also I would never initialize a store on the server that seems weird. That's your source of truth and you should be updating a store on the client based off of that source of truth, I'm not sure managing state on your server is something you're supposed to do. On the other hand writing sql statements in a react component didn't used to be something we are supposed to do either.
|
# ? Feb 10, 2024 09:35 |
|
necrotic posted:If your route ended in a / the ./ would work like you desire. A regular old anchor tag behaves the same way. Oh interesting, I never would have thought the trailing slash might be relevant. I tried adding a trailing slash but it still cuts off the last node when linking to ./ The trailing slash isn't visible in the url bar though so maybe Next cuts it off. Jabor posted:I'm pretty sure the only reason this: No, if I removed the fixed /slots/ fragment from my route then the generated link would cut off the {a} instead so it would still fail. It would link to /category/{b}. The last node of the URL always gets cut off when linking to ./ Jabor posted:(Or can trivially be made to work by just modifying the link, like make it "./slots/{slotId}") Yeah this was the fourth example in my list, it works but requires a fixed fragment between every dynamic route. Nolgthorn posted:I've been playing with this stuff too. Oh yeah I think all the routing stuff is really cool too! I'm just still getting my head around it. But yeah it's really fun. I could definitely just have category/{categoryId} and /card/{cardId} etc. It's mostly about UI and navigation: I have a list of categories, and then you click one to open up a list of slots, and then you click a slot to open up a list of cards. So the UI drills down two layers but keeps bits of the first two layers visible. It makes sense to me in that situation to have a route with three layers too. Maybe I could do the same thing with parallel routes or something and keep everything on the same layer, but I can't immediately see how.
|
# ? Feb 10, 2024 11:14 |
|
Following a beginner React course. Created this rather ugly to-do app. https://codesandbox.io/p/sandbox/todo-almost-forked-znfh4d?file=%2Fsrc%2FApp.js%3A187%2C1 Adding a person works. Removing a person works. Rendering the to-dos works. Ticking off to-dos... is a work in progress and I'm not sure why. When I tick a task in the ShowTodosForm, the count goes down in the sidebar. And if I click to a different person and back to that person, their todos are fine. However, if not then the item doesn't go away - and if I click to the other person the first item is ticked for them too. I'm not really sure how to diagnose this so would love a pointer. Thanks.
|
# ? Feb 11, 2024 21:59 |
|
Sad Panda posted:When I tick a task in the ShowTodosForm, the count goes down in the sidebar. And if I click to a different person and back to that person, their todos are fine. However, if not then the item doesn't go away - and if I click to the other person the first item is ticked for them too. When you switch between selected persons, you're still rendering the same component tree. Any elements in the DOM that are shared with the previous selected person's render will be kept in place. Only the differences are applied as DOM transformations. So, as long as each list has some number of todos in it, and todos always render a checkbox input, there will be some checkbox inputs that get reused. You can opt out of this by setting a unique key prop, which tells React to treat something as a unique instance of a component or element. I would try updating the key here on the <Todo> to be a unique value for each person and todo combination: Diff code:
|
# ? Feb 11, 2024 22:33 |
|
Related to that, you are using an uncontrolled input for the checkbox, so if it is reused, it will stay checked. So passing in a value for the checked attribute might fix it.
|
# ? Feb 11, 2024 23:06 |
|
Thanks for that. I've changed the key, and that does indeed stop the same ID checkbox being ticked. It still doesn't immediately pop that item off my to-do list - I've coded it so when I check it, it pops it from the list.JavaScript code:
smackfu posted:Related to that, you are using an uncontrolled input for the checkbox, so if it is reused, it will stay checked. Thanks - I was wondering about that. To me I wasn't sure what value to assign to it. If I had a boolean of completed, then that'd make sense to toggle it. As is I just want to pop it so unsure what value would work for it. Sad Panda fucked around with this message at 21:44 on Feb 12, 2024 |
# ? Feb 12, 2024 21:41 |
|
Sad Panda posted:It still doesn't immediately pop that item off my to-do list - I've coded it so when I check it, it pops it from the list. Even though you're updating the state in peopleData, you're not updating the state in selectedPerson, which has a copy of the old person object. Instead of storing a copy of the entire person object in state, try storing a selectedPersonId, and then use a memo to derive the selected person from selectedPersonId and peopleData whenever either of them changes: JavaScript code:
|
# ? Feb 12, 2024 22:04 |
|
Ima Computer posted:Even though you're updating the state in peopleData, you're not updating the state in selectedPerson, which has a copy of the old person object. Thanks for the push. I'd not learnt about useMemo yet so I fixed this instead by... Storing the person's ID not the person. This meant in handleTaskChecked I could do it like this. JavaScript code:
JavaScript code:
|
# ? Feb 21, 2024 17:54 |
|
Hi thread! I'm pretty embarrassed to be posting this because I'm positive that I'm overlooking something so stupidly simple that I'm an idiot for not being able to see it. This is my first real coding attempt in something like 12+ years so I've forgotten most everything and have been trying to cobble stuff together. The project: I'm trying to build a filterable gallery using the base code provided here: https://www.codingnepalweb.com/filterable-image-gallery-html-bootstrap/ However, instead of just one group of filters, I have multiple groups of filters and some of them should be single selection only while others are multiple selection. Single selection filters:
Multiple selection filters:
Toggling the filters on/off should update the results in real time. So if a user selects "standalone", "Kindle Unlimited", "YA", "short", "mystery" and "action", the only books that show should be short standalone books intended for a YA audience that are available on Kindle Unlimited and are either in the mystery or action genres. Current status: I've been able to get the visibility of whether a button is selected or deselected working mostly right so I'm using const selectedFilters = document.querySelectorAll("#filter-buttons .active"); to then figure out what should/shouldn't be showing. I'm then splitting those into two separate arrays, selectedFilterLimits to represent the single selection filters and selectedFilterParams to represent the multiple selection filters. Somewhere along the way of trying to get the results to display as I want them to, I screwed up and now the filters don't deselect properly. . My fail code, which has numerous redundant bits in it from abandoned previous attempts at getting something to work, as well as a couple of parts where I'm SURE it's the culprit but my eyes are totally crossing and I can't figure out the fix: JavaScript code:
|
# ? Feb 22, 2024 04:31 |
|
I don't have anything to contribute but I want to compliment your easy to read well organized code.
|
# ? Feb 22, 2024 15:10 |
|
Nolgthorn posted:I don't have anything to contribute but I want to compliment your easy to read well organized code. Leng posted:
|
# ? Feb 22, 2024 16:13 |
|
Leng posted:If anyone could point me in the right direction, I would be very grateful for the help! From skimming the code: You seem to be using a non-checkbox element like a checkbox, you could try using checkboxes and trigger your filtering with the "input" event. You also seem to be doing both the active/not active toggling and filtering in the same pass. I would do the toggling in one function, then run a separate function that just gathers the current selection and filters on that.
|
# ? Feb 22, 2024 23:18 |
|
roomforthetuna posted:I do not find these indents-not-matching-brackets to be well-organized or easy to read, and I suspect without having done much inspection that the problem lies in a condition being in the wrong place from this. Run it through an auto-formatter! (Though I also would be suspicious of a block that says it removes something calling Array.push which is an action that doesn't remove anything.) Wheany posted:From skimming the code: You are both 100% on the money. I am the stupid. I indeed messed up the conditions and also tripped myself up by not separating out my functions. I managed to impose on two others outside of this thread to take a detailed look and they very kindly turned my travesty into this elegant script: JavaScript code:
Thank you all for taking a look!
|
# ? Feb 23, 2024 01:26 |
|
|
# ? May 13, 2024 06:58 |
|
One of the biggest lessons to learn from that help is to work at breaking down what you are doing into smaller chunks. One big function doing a lot of stuff is generally a signal that it can be broken down into smaller "units of work" that each individually solve a smaller part of the larger problem. This turns out to be one of the harder things for people to "figure out", in my experience, but can be a huge boost on writing at least decent code. Any time you find yourself struggling to resolve an issue, take a step back and see if you can break down what you're working on into smaller pieces. That process alone might lead you to resolving whatever issue, but if not it can help you narrow down where it is and then focus on that specific part. I believe this is what you are acknowledging with quote:maybe the next time I write some code, it won't be several hundred lines of brain vomit. so don't take my post as a "you got the wrong lesson", just an aid on top if anything. And to add a bit more: figuring out how to break things down never goes away. It may become easier to see where things can be broken down, but you will at some point find yourself back here going "okay I have this thing and... what's wrong?". necrotic fucked around with this message at 01:43 on Feb 23, 2024 |
# ? Feb 23, 2024 01:40 |