Organizing data with Laravel Collections

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Hey everyone, Andrew here!

I'm back this time with a fairly long (30 minute) video that I put together showing off one of my favorite features of Laravel - Collections.

I go through how to get started creating one (spoiler alert, just pass in an array to collect), and then showcase 12 different methods using JSON straight from reddit to sort, organize, and filter posts and post elements that we want from that data.

I've also added breakpoints in the description of the video if you want to just skip through and get the gist of it, or watch it on 1.5x speed, lol.

πŸ‘οΈŽ︎ 8 πŸ‘€οΈŽ︎ u/aschmelyun πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

I love your keyboard's sounds πŸ₯ΊπŸ₯Ί

πŸ‘οΈŽ︎ 3 πŸ‘€οΈŽ︎ u/Shady980 πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

Which IDE is that one?

πŸ‘οΈŽ︎ 3 πŸ‘€οΈŽ︎ u/SirDale πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

Thanks for posting videos. I really like your format and how you explain stuff. :)

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/stoybuild πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

Cool, I've been using Linq since it came out on c# a lot of years ago and I've been wanting this functionality on Php since then.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/patroklo πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

Awesome! I’ve been learning laravel the last few weeks. Really like it!

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/w00ddie πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies

I was really scared of docker. Your docker tutorials came to an aid. You make things really easy to understand. Now I love docker. Thank you

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/tahmidrana πŸ“…οΈŽ︎ Oct 18 2020 πŸ—«︎ replies

It’s a bit weird that you keep copying those template and only changing the title. β€œTitle” variable and a single template would save you some time.

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/DevelopmentRare1658 πŸ“…οΈŽ︎ Oct 16 2020 πŸ—«︎ replies
Captions
hey everyone andrew here one of my favorite features of the laravel framework is the simple elegance of collections these are essentially powered up arrays that give you the ability to run and chain a wide variety of methods onto them in order to sort organize and filter given data in this video i'll be showing you a select set of these methods and provide some insight on how and why you would use them with a real world large data set first things first we have a blank larval app fresh out of the box set up on a local development environment let's open up the code and head over to our routes web file for this video i'm going to demonstrate each method as a different route but they'll all be wrapped up in one controller i'm going to go ahead and use artisan to create that controller now and we'll just call it collection controller alright now that that's all set we can modify the landing route to use our new controller because this is laravel 8 i'm using the new route notation of calling an array as the second argument to route get and passing in our controller class then the method name index let's open up the collection controller and create that index method for now i'm just going to return a simple string to test out what we did hello collections heading to our browser it looks like our index route is working so what data are we going to use for our collections in various methods there's quite a few free apis out there but i wanted to use something that would contain a good amount of variety and some excessive data to show just how powerful that collections are at getting through all of that if we head over to one of my favorite subreddits i'm going to show you something that you might not know you can append.json to any url on reddit and get a raw json feed of the data returned there's no need for an api key or any kind of authentication so this is perfect for our example app there's a ton of data here and a somewhat complicated and complex structure perfect for filtering and sorting through if we take a look at the collection documentation on larval's website you can see that our description from earlier holds up collections are a fluent convenient wrapper for working with arrays of data you can also check out the dozens of methods that are available to use with them and all that we need to do to create one is pass in an array to the global collect method available throughout the larval framework heading back to our collection controller let's add in a private posts property then let's create a constructor that grabs the subreddit json that we saw earlier using laravel's built-in http library finally we populate posts as a collection consisting of the subreddit's individual posts found as the data children items in the json feed doing this in the constructor we can initialize and access the post collection from any method that we decide to tack onto this controller let's make sure this works by replacing the hello collections return with the post property that we just initialized heading to our browser and refreshing we are presented with our collection since we're returning the whole thing laravel is automatically dumping it out as json so that's expected well how about we do something to show off our data in a little bit more of a visual way let's create a view called collections index and pass in our post property now i'm just going to scaffold out a simple layout template for this view and any other ones that we decide to use using the default view as a starting point that looks good so let's work on our actual collections index view extending the default layout let's add in a title we can then run a for each loop over the collection treating it just like a regular array and we'll output a link to each of the posts both the url and the title are kept under the data index okay let's see how this looks perfect we have each of our posts from the subreddit json feed displayed out in this view clicking on one opens up the url submitted for that post as well and here's where collections can come in handy this top item here isn't a link to an image it's a link back to reddit with a text post what if we wanted to easily remove any non-image posts from this feed let's head back to our code and we can get started with our first example the filter method in our routes web file we're going to create a new route filter and connect it to a filter method on our collection controller with an array in php we might be tempted to do something like initialize an array of filtered posts then run through a for each loop of the post and add in a post to that array if it passes a set of criteria but with collections we can chain on the filter method this works a bit like the array filter method in vanilla php the only argument is a closure function consisting of the current item in the collection and the key then depending on the boolean value of the return that item is either kept or discarded looking back at our data source there's a post underscore hint attribute under each post that can be used to determine if the post is an image so we can return the result of a conditional checking that the post hint equals image and then add the new filtered post to a collections filter view for display you can also run multiple conditionals within the closure breaking for a boolean return to exit early for instance if a post hint doesn't equal an image we want to immediately discard that post continuing if it does we want to only keep those posts whose url contains the i.red.itdomain and we run that comparison with laravel's str contains helper in order to display these filtered posts let's copy our index blade template as filter blade update the title to reflect the contents and add in the thumbnail from the post as well since each post has an image we know the thumbnail will always be present alright let's see what that looks like perfect our filtered posts just containing images from reddit's image host are displayed just as expected let's move on to our next example pluck just like with the filter demo we'll create a new route and collections controller method just for this pluck is an insanely useful method and what it does is it allows us to pull out values nested in large data sets and create flattened arrays with just those values for example let's take the filtered image post that we just created then let's tack on the pluck method passing in data.url after that the all method will retrieve all of those values found as an array the dot notation used here signifies a nested attribute data corresponds to the data key of each post element and then the url key under that array it traverses each post taking the url out of each of them and puts them into our post variable as a single flattened array of urls just like we did previously let's create a new corresponding view from our filter blade template since this is a flattened array each image represents a string consisting of the url so we're just going to display these images outright by echoing that value in the source attribute loading up our pluck route and everything is displaying correctly each image from our filtered posts is being shown and our large data set that we were traversing earlier has been reduced to a small array of urls next on the list is contains adding a new route and method to our controller let's start out by pulling in our code from the pluck example and make a quick modification to the copied blade template now let's say that you wanted to do something like show a different view if no posts were found from our filter method you might add a conditional to check if the post array is empty and then perform your action based on that value however there's a caveat you're wasting processing power and memory by running the filter first and depending on the amount of data and complexity of your collection that could eat up valuable resources instead that's where contains comes in we can call this post contains and pass in the key or nested key with that notation as well as the value that we're looking for what this does is returns a simple boolean true or false depending on if the value in the second argument is found in any of the elements under the key provided throughout the whole collection that way we save time and resources determining if we even need to run the filter in the first place let's create this blade template for an empty collection and see how this works navigating to contains we see that we're pulling in post images as expected now let's change the data source to a subreddit that doesn't use images like askreddit navigating back we see that we're displaying the blade template for an empty collection showing that contains has returned false next on the list group by i'll just create our route and controller method for it and let's do something a little different with this one we're going to use the filter method and only pull in posts that have a post hint of self or image using the return value of in array chaining onto that we're going to call group by and pass in the nested data post hint key with that notation finishing it up to array which will as you might expect return the collection as an array what group i is going to do is return back our collection broken up into separate child arrays based on the posts and value for each element those arrays will be keyed by the unique values of the post hint attribute in this case either self or image to see why this is helpful i've created a new blade template looping over each post as a type associated with children we can just include a separate blade file determined by the value of that type variable we know that we have two possibilities self and image for self let's go through each of the children posts and echo at the value of this self-text underscore html attribute for images we'll just show the image contained in the url now if we visit the group by route we can see our data has been broken down into two groups this self post first listing out any that might be here and then the image posts following let's return the raw posts and i'll show you what the array actually looks like see we have our two group arrays keyed as self or images and then under them the items whose data posts and attributes contain those respective values okay following this we have sort by route and new controller method and we'll start by pulling in the group by code from earlier let's remove the group i call and replace it with sort by passing through the data title nested attribute using dot notation after that a call to values resets any keys of the original array and finally all to ensure that the entire collection comes through i'm also going to update the filter here to show us only image post hints let's create a new blade template to see if this changes our data display loading up the sort by route this method is pretty self-explanatory it sorts the data by the attribute that you pass in in our case it's currently sorting by the title alphabetically by default this works in the ascending order if we wanted to swap that we unfortunately can't pass in a second argument to just say descending but we can update the method to call sort by desc instead and that will reverse the order all right next up we have one of the more interesting ones partition after creating our route and controller method let's hop back over to the original data source from reddit you can see that nested in each post data object there's an ups attribute this is the amount of upvotes as an integer that the post has currently received now let's say that we wanted to split our posts into two separate collections based on that value that's where the beauty of partition comes into play if we create two variables using list let's say popular posts and regular posts we can use this post partition and pass in a closure function with a post object as the only argument then those two collections are populated by the boolean value return in that closure for instance we're going to return true if the post's data ups attribute is greater than a thousand this means that posts that have over a thousand upvotes will go into the popular post collection while the rest will go into the regular post collection let's create a blade template for these and see how we can display them we'll pass in both collections update the title of the view and run two for each loops one for each collection displaying the link and the thumbnail for each of them separated by popular posts and regular posts headings all right let's navigate to the partition route and okay maybe we shouldn't have the thumbnail since not all of these are images showing the actual upvote amounts might be a bit better you okay that's looking good you can see they're separated by posts that have over a thousand up votes and those that don't although the order is a little messy luckily though since partition returns collections we can call sort by on both of them directly let's sort them both by descending and by the ups amount perfect keeping this going with a new route and collections controller method our next example is reject pretty straightforward for how it sounds this method works similar to filter but purely removes elements based on the true and false return of the closure function using the idea of popular posts as an example let's reject any posts whose ups amount is less than a thousand and return a view to display these because the post variable is a collection like with partition we can sort the results by the data ups amount just making some slight adjustments to our view and let's see how this looks alright we have our list of popular posts ones that have over a thousand upvotes and they're sorted in descending order next up wherein just creating a new route and controller method for it and let's pre-populate this with the code from our group by example earlier this whole filter block right here where we're using a closure to determine if the post hint value is one of an array of possibilities can be reduced drastically using wherein we just have to pass in the key as the first argument and it can be nested using dot notation like our other examples then the array of possible values for that key as a second argument this will return just those posts whose post hint value is either self or image let's create a new blade template for this method just like we did with the group by example and navigating to the wherein route we can see the results we're expecting the same self and image post groups just with a little bit more simplified syntax now let's take a look at chunk after we create a route and controller method for it this is a pretty straightforward and simple method but can be very useful when it comes to front-end development using the chunk method your collection is broken into smaller arrays the amount of each is determined by the integer passed into the method's argument we're using two here and then adding them to a new blade template in that template instead of running a for each loop on the post to get an individual post we're getting a chunk containing two posts each in this loop we can do layout and markup additions like add in a bootstrap row and then we can run a full reach on the chunk to get the individual posts and continue with our layout now if we navigate over to the chunk path we see two posts each separated by rows in the source this is verified with each chunk being represented by a bootstrap row and each of those row elements containing two individual posts moving on we have a super simple method called counts let's create the route and collection controller method for that and we'll pass in the code from the reject example earlier in our layout for it let's say that we wanted to display the amount of posts that were in our collection we could call count directly on posts but only if we use the two array method first or we can just use the collection method count and visiting the count route we can see that there is seven popular posts here just as expected okay i'll admit that was incredibly simple we're almost done here but now let's take a look at first creating a route and controller method for it what if we want to return a single post that meets a condition using this post first it expects a closure function looping through the posts as soon as the return of that function is true the current post object will be returned and the loop stopped let's find the first post that has over a thousand upvotes and use a new blade template to display this all right visiting the first route and it looks like that's exactly what we're expecting it has over a thousand upvotes however there's another similar method that we can use to simplify this further because we're returning the result of a comparison in the closure we can change first to first where then pass in the key whose value we're comparing in this case it's nested using dot notation and after that our comparison operator greater than finally the value that we're comparing one thousand this single line accomplishes the same thing as our closure function did earlier and we can prove that by heading back to our browser and refreshing see exactly the same okay on to our last example tap let's create the final test route and controller method and pre-populate this with the code from the sort by example below the sort by descending call let's add in tap now tap is an interesting method because it doesn't actually affect the collection in question at all tap allows you to accomplish something between collection methods grabbing the whole collection in its current state without affecting the values that are being returned back so for example let's say that after sorting we want to log the ids of the posts that are in the current collection tap takes a single argument a closure function with the collection and inside of that we can write to the log we'll display some text the number of items in the collection using the count method and then the ids by pulling them into a flattened one-dimensional array with pluck finally let's create our test blade template and see how this works we'll have to load up the tap route and while it doesn't look like anything has happened let's check the log there it is we've logged there are 24 posts and the ids from each of them have been dumped in here as well alright well that about wraps it up for this video you've learned about creating and working with laravel collections including 12 different methods that you can use to sort and organize larger data sets huge thanks to my github sponsors and everyone else who continues to support these videos as always if you have any questions about this or any other web development topics please feel free to reach out to me in the comments or on my twitter linked below thanks for watching
Info
Channel: Andrew Schmelyun
Views: 16,236
Rating: undefined out of 5
Keywords: laravel, laravel tutorials, php, php tutorials, laravel collections, web development tutorials, web dev, php development, laravel development, laravel tutorial
Id: a2QvlLs0uEk
Channel Id: undefined
Length: 32min 51sec (1971 seconds)
Published: Mon Oct 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.