Axios is a lightweight npm package that makes requesting data easier than Javascript's built-in Fetch API. In this tutorial, you will learn how to add Axios to your project and use it for all CRUD (create, read, update, and delete) operations in the project. If you are just starting out with React, I suggest starting at the beginning of this Learn React series playlist here: th-cam.com/play/PL0Zuz27SZ-6PrE9srvEn8nbhOOyxnWXfp.html
It really discourages me learning when I bump into an old version of React Router... I was watching and practicing all of your lessons until I've come across an old version of React Router...
OMGGGGGGG!!!! I was looking for React Axios video and your video came up to my recommendation!!! XD!!! Besides, I'm 1st visitor to this video!! haha Thank you Dave~ !
i'm just going to give my friendly feedback: i know time is valuable, and people are learning at all different levels, but even as far as just learning axios, this seems like less of a tutorial and more "dave (briefly) shows people how he does things". while i of course don't expect you to be explaining how destructuring works and things like that, i don't really see the point in a tutorial that goes from point to point without even explaining what each step is generally accomplishing. I'm good with going back to docs to understand things, but if I can't really understand why I'm doing a thing, there's very little point. just a little more time spent on that would be a massive difference. Anyway I appreciate the effort and you seem like a great teacher, this is just feedback on this particular video.
This is what I exactly feel after seeing Dave Gray's tutorials, they are not for absolute begineers, I had to study react from the documentation and then see this playlist, even for it to just make sense
He explains it in /watch?v=XYrNkTkx8Uc, this video is "How to accomplish with AXIOS the same things we did with fetch in default react". If you come upon this video by just searching something like "how to use AXIOS" and haven't watched the previous one then it may look a bit rushed, but explaining everything again would be redundant for people who are following the series step by step.
@@TheLastPhoen1x Yeah, that's fair, but the nature of TH-cam kind of dictates the format. When I buy a full course, then of course I don't want redundancy, but YT videos should be self-contained in my opinion. Which is why I prefer Web Dev Simplified or Net Ninja to 90% of what's on TH-cam, simply because everything is included.
Dave, as an avid youtube tutorial consumer, I must say your teaching is outstanding. After watching the Node/Express/MongoDB series which contains an extensive section on authentication and JWT authorization I was looking forward to your React client side implementation… Did I miss it? If not, your contribution in that area would, I am sure, be appreciated by many.
Hi, this might be a dumb question, but I don't understand the importing of api from ./api/posts :( api is a folder, right? So if you want to import api, wouldn't be "from ./api" enough? And if you chose "from ./api/posts", shouldn't you be importing posts instead of api? (Sorry for my english, I'm not a native speaker.)
"api" there is just an arbitrary name. What happens there is basically IMPORT [whatever is marked as "export default"] from the file "/.api/posts" and refer to it thereafter as "api" (or whatever name you want to give it).
just in case someone having trouble with rendering edit-component after refactoring to react-router-6. Look at PostPage and change the edit Link to ......and be happy.
You're welcome! This video uses Axios which is not quite the same as the built-in Javascript Fetch API. I do have a tutorial about using Fetch here: th-cam.com/video/VmQ6dHvnKIM/w-d-xo.html
Clarifying question, for the first parameter inside of the AXIOS call which is the path `/posts/{id}`, id is a numerical value, does the URL path only work with numerical values? For example, if I tried to find a post using the title property instead of the id which stores a string value, and the path was `/posts/{title}` that doesn't seem to work, why is that?
That is all dependent on what your backend server expects to receive. If my memory is correct, this tutorial uses a mock API ran with JSON Server. It expects to receive the post id when requesting a specific post - which is not unusual. Here is another practice API that you can read about and see how it expects to receive requests: jsonplaceholder.typicode.com/
that subscribe sound 3:53 sounded to me as some has coughed in the room while im alone. anyway this tutorial is very very AWESOME for someone like a beginner like me. Thanks so much!!!! very very helpful!
Dave in the timeframe 26:32 the dependency list of the useeffect post,setEditTitle and setEditBody seems redundant to me because individual post is not gonna change so it will not trigger the useeffect. Every functionality works fine with empty dependency list. Whats the reason of adding the setEditTitle and setEditBody and post over there?If empty list works fine
if you use any functions or variables in a useeffect, you need to include them in the dependency array . That's just the rules otherwise you will get warnings
Somewhat unrelated question, but I'm going through a university Web Security course right now. Our textbook states that bad hackers can gain clues on how to hack the system from error messages that are too detailed. The error messages provide them with clues. Should we log error messages to console if that is the case? Maybe this applies more to server side than client side error messages...? Just curious on what you think about the way to structure error messages and on logging them to console.
Good question, Michael. It's all preference really. The console.error and other console statements are typically removed in production deployments. On the backend, errors should be logged. On the frontend, you can choose what to display if you want to display them in production.
Please I need help, I'm fetching the data from the API but it not displaying any data(info) I don't know if it's API or my error and I'm just learning how to call API using axios, including the requestconfig and so many more
Thank you for great tutorial serie. I am afraid that I have some questions: Is there any reason that you prefer PUT vs PATCH request for axios? I tested and there is not visible difference, are there any performance or other aspect to be aware of?
Good question! You won't see a difference with PUT vs PATCH. PATCH is supposed to be for partial modifications while PUT is for replacing the entire record. That is why I used PUT. All data was being replaced. More request type definitions on MDN here: developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Hey Dave, I have a bug in my app so I'm thinking it could possibly be in yours as well? I'm not exactly sure what the issue is but when I click on a post, edit post, and delete all of the title (completely blank), it automatically takes me to "Page not found." Please let me know if you experience this issue as well and what's the fix. Thanks! Also, really enjoying your series!
Thanks - no problem in my example code - BUT things to consider: 1) If you are on the blog project, look for the updated React Router link in the description because React Router was updated after this course was released. 2) React is now on React 18 instead of React 17, but this should not have an impact in the code for this course. Nevertheless, it is worth noting.
Thank you. The JSON server API we set up is just for our development environment. You cannot host an API on Github Pages. If you complete my Node.js full course for beginners, you will learn to build your own REST API. You can then host it Heroku or Glitch or Repl (and more) for free.
@@shravanp8091 Netlify will host React and other frontend projects, but it does not host backend projects that run on a server - Node.js, PHP, Python, and other backend technologies.
I am building a blog in react aswell and what i ve done,is i ve set up an express server connected to my database to handle data,is it wrong,or is it just an other way?
It is not wrong. It is a great way to do it! This course / playlist just focuses on React so we set up a fake REST API with JSON server instead of building a backend.
Sir after I wrote the code for the update posts everything was working fine. But the app won't allow me to create changes in the posts. It says ' failed to load resource'. Is there anything I could have possibly missed?
@@DaveGrayTeachesCode sir i checked and i have done everything correctly. Only the Routing part is different in React 18. I think it's an error in my computer or system itself. However, I understood the axios api concept very well. So thank you for the video and the reply!
Hi Dave, I'm researching this, and I have a question since I see you don't address it in the video. I see you are hardcoding "localhost" on the axios.create() function. How do you handle the way the app works in production vs locally? What's the method you use to check if you are running on a deployed version? I've been using the interceptors, but I'm just guessing you can give a much more precise answer and correct way on how to do this. Much appreciated.
Good questions, Daniel! After development, I often switch out "localhost" along with any port number so "localhost:3000" for example - and change it to the actual web address of the REST API I will be using. The routes you use in development - that is the part of the address that comes after the base URL like /posts or /todos or /whatever - those routes should be the same in development that you will use with the actual REST API. To answer your other question, you can check to see if React is in "development" or "production" mode with this value: process.env.NODE_ENV ..use a console.log() statement to check the value in your index.js.
Sir I have a small question... Why did you put setEditTitle, setBodyTitle as dependency for useEffect at 26:58. I don't think it is needed there as that function only has to run at load time
Besides they both are sort of functions to set the values of editTitle and editBody, isn't it? Then their value would never change so why to put them as dependency?
Good question! You are right that they will not change and should not be needed. However an eslinter doesn't recognize this and adding them doesn't harm anything. I think I did it to avoid the warning from an eslinter like this one: "React Hook useEffect has a missing dependency: 'setSomeState'. Either include it or remove the dependency array. eslint(react-hooks/exhaustive-deps)"
Hi Dave. Thank u for this awesome tutorial. I have a doubt, why the useEffect function at EditPost.js is not been called everytime the state of input field changes? If you put that function (setEditTitle) in the dependencies why this not triggering the useEffect? Thanks
You're welcome! 💯 React understands that the setState function is not changing. useEffect will only run if the dependencies listed in the dependency array change.
@@GilbertoTrin setState won't change, but older versions of React used to give warnings if you didn't include it in the useEffect dependencies. It is not necessary and I think the warnings for setState have been stopped, too.
Hi Dave. Thank u for this awesome tutorial. I have a doubt , Can we use axois to fetch data from firebase? I believe we don't need the json server in that case. Please let me know. Thanks.
Yes, JSON server is just for your dev environment. You can use Firebase for the backend of your app in production or a Node JS backend like I show how to build in my Node JS for Beginners course.
@@DaveGrayTeachesCode Thanks Dave. I will try to connect to the firebase DB and update u if I have any issues. Appreciate all ur great efforts. U r the best instructor I have seen so far on TH-cam. May God bless u !!!!
Great tutorial, many thanks for this. However you seem to be missing the useEffect return and aborting the API calls - I know you want to keep this simple but you didn't mention aborting and possible issues.
Thank you and you are right that I wanted to keep this simple here in a beginners course. The examples you are looking for are here: th-cam.com/video/NqdqnfzOQFE/w-d-xo.html
@@DaveGrayTeachesCode Excellent, thanks for the link Dave, I'll check that out, I noticed in the next video however "custom hooks" you go over the clean up a little. Loving the series!
On 29:08, Dave put handleEdit on the button instead of onSubmit event inside the form element. I tried to put it on the onSubmit event and it worked, the post did change but then after I passed on e.preventDefault(), it stopped working. The console printed something about "uncaught in promise". Anyone care to explain?
At 29:08 - as you noted - I show how to do this. You could create a handleSubmit function above the returned JSX which has both the e.preventDefault() in it as well as the call to handleEdit with the post.id passed in. In this beginners tutorial - I show in the example at 29:08 - how to do this with functions created directly inside the JSX.
I followed this video When i'm updating and deleting the user(instead of post ) i'm seeing this error "Failed to load resource: the server responded with a status of 404 (Not Found)" Even i checked in the backend controllers i have used this code in update export const updateUser = async (req, res) => { const { id } = req.params; const { email, first, last, avatar } = req.body;
if (!mongoose.Types.ObjectId.isValid(id)) return res.status(404).send(`No post with id: ${id}`); const updatedUser = { email, first, last, avatar: id }; await User.findByIdAndUpdate(id, updatedUser, { new: true }); res.json(updatedUser); }
Axios is a lightweight npm package that makes requesting data easier than Javascript's built-in Fetch API. In this tutorial, you will learn how to add Axios to your project and use it for all CRUD (create, read, update, and delete) operations in the project. If you are just starting out with React, I suggest starting at the beginning of this Learn React series playlist here: th-cam.com/play/PL0Zuz27SZ-6PrE9srvEn8nbhOOyxnWXfp.html
It really discourages me learning when I bump into an old version of React Router... I was watching and practicing all of your lessons until I've come across an old version of React Router...
The best React ( the whole series ) explanation on entire internet. I love you approach, thank you man
You're welcome! And thank you for the kind words 🙏
OMGGGGGGG!!!! I was looking for React Axios video and your video came up to my recommendation!!! XD!!! Besides, I'm 1st visitor to this video!! haha Thank you Dave~ !
That's great! You're welcome 🙏💯
i'm just going to give my friendly feedback: i know time is valuable, and people are learning at all different levels, but even as far as just learning axios, this seems like less of a tutorial and more "dave (briefly) shows people how he does things". while i of course don't expect you to be explaining how destructuring works and things like that, i don't really see the point in a tutorial that goes from point to point without even explaining what each step is generally accomplishing. I'm good with going back to docs to understand things, but if I can't really understand why I'm doing a thing, there's very little point. just a little more time spent on that would be a massive difference. Anyway I appreciate the effort and you seem like a great teacher, this is just feedback on this particular video.
This is what I exactly feel after seeing Dave Gray's tutorials, they are not for absolute begineers, I had to study react from the documentation and then see this playlist, even for it to just make sense
He explains it in /watch?v=XYrNkTkx8Uc, this video is "How to accomplish with AXIOS the same things we did with fetch in default react".
If you come upon this video by just searching something like "how to use AXIOS" and haven't watched the previous one then it may look a bit rushed, but explaining everything again would be redundant for people who are following the series step by step.
@@TheLastPhoen1x Yeah, that's fair, but the nature of TH-cam kind of dictates the format. When I buy a full course, then of course I don't want redundancy, but YT videos should be self-contained in my opinion. Which is why I prefer Web Dev Simplified or Net Ninja to 90% of what's on TH-cam, simply because everything is included.
Dave, as an avid youtube tutorial consumer, I must say your teaching is outstanding. After watching the Node/Express/MongoDB series which contains an extensive section on authentication and JWT authorization I was looking forward to your React client side implementation… Did I miss it? If not, your contribution in that area would, I am sure, be appreciated by many.
Great suggestion! I need to create a tutorial to tie that together 💯
@@DaveGrayTeachesCode is there a tutorial connecting react and node with authentication Dave?
If yes, please provide the link. Thanks
I've been waiting for this one. Thank you Dave for these react series are awesome.
Thank you for the kind words Leonardo 🙏🚀
Impressive, can tell you are a very experienced developer when you code on the go, while speaking.
Thank you for the kind words 🙏💯
6:09 also I am going to move my mouse over here and do a slight tap on the left side of the mouse to perform a left click
TYSM Mr.Gray super helpful !!!
Hi, this might be a dumb question, but I don't understand the importing of api from ./api/posts :( api is a folder, right? So if you want to import api, wouldn't be "from ./api" enough? And if you chose "from ./api/posts", shouldn't you be importing posts instead of api? (Sorry for my english, I'm not a native speaker.)
"api" there is just an arbitrary name. What happens there is basically IMPORT [whatever is marked as "export default"] from the file "/.api/posts" and refer to it thereafter as "api" (or whatever name you want to give it).
What will be the route for editpost element in version 6. Can you please help me with it. Thanks,.
just in case someone having trouble with rendering edit-component after refactoring to react-router-6. Look at PostPage and change the edit Link to ......and be happy.
Thanks for the reminder, I implement this with and put the edit route underneath the post route as
hey dave, I am having a hard time understanding the built in fetch API of javascript , this tutorial helps me a lot.. thanks
You're welcome! This video uses Axios which is not quite the same as the built-in Javascript Fetch API. I do have a tutorial about using Fetch here: th-cam.com/video/VmQ6dHvnKIM/w-d-xo.html
Clarifying question, for the first parameter inside of the AXIOS call which is the path `/posts/{id}`, id is a numerical value, does the URL path only work with numerical values? For example, if I tried to find a post using the title property instead of the id which stores a string value, and the path was `/posts/{title}` that doesn't seem to work, why is that?
That is all dependent on what your backend server expects to receive. If my memory is correct, this tutorial uses a mock API ran with JSON Server. It expects to receive the post id when requesting a specific post - which is not unusual. Here is another practice API that you can read about and see how it expects to receive requests: jsonplaceholder.typicode.com/
that subscribe sound 3:53 sounded to me as some has coughed in the room while im alone. anyway this tutorial is very very AWESOME for someone like a beginner like me. Thanks so much!!!! very very helpful!
😂 Didn't intend to scare you. I'll have to listen to it again.
@@DaveGrayTeachesCode haha you dont have to reupload the video! it's unique! thanks for replying, felt special :)
Dave in the timeframe 26:32 the dependency list of the useeffect post,setEditTitle and setEditBody seems redundant to me because individual post is not gonna change so it will not trigger the useeffect. Every functionality works fine with empty dependency list. Whats the reason of adding the setEditTitle and setEditBody and post over there?If empty list works fine
if you use any functions or variables in a useeffect, you need to include them in the dependency array . That's just the rules otherwise you will get warnings
Somewhat unrelated question, but I'm going through a university Web Security course right now. Our textbook states that bad hackers can gain clues on how to hack the system from error messages that are too detailed. The error messages provide them with clues. Should we log error messages to console if that is the case? Maybe this applies more to server side than client side error messages...? Just curious on what you think about the way to structure error messages and on logging them to console.
Good question, Michael. It's all preference really. The console.error and other console statements are typically removed in production deployments. On the backend, errors should be logged. On the frontend, you can choose what to display if you want to display them in production.
Please I need help, I'm fetching the data from the API but it not displaying any data(info) I don't know if it's API or my error and I'm just learning how to call API using axios, including the requestconfig and so many more
Please what can I do to my the data visible
Thank you for great tutorial serie.
I am afraid that I have some questions:
Is there any reason that you prefer PUT vs PATCH request for axios?
I tested and there is not visible difference, are there any performance or other aspect to be aware of?
Good question! You won't see a difference with PUT vs PATCH. PATCH is supposed to be for partial modifications while PUT is for replacing the entire record. That is why I used PUT. All data was being replaced. More request type definitions on MDN here: developer.mozilla.org/en-US/docs/Web/HTTP/Methods
hello sir. why does it say bash in your terminal. Did you change any settings from default. My terminal shows cmd
I installed the bash terminal when I installed git. If you have more than one, you can choose from a drop menu.
Hey Dave, I have a bug in my app so I'm thinking it could possibly be in yours as well? I'm not exactly sure what the issue is but when I click on a post, edit post, and delete all of the title (completely blank), it automatically takes me to "Page not found." Please let me know if you experience this issue as well and what's the fix. Thanks!
Also, really enjoying your series!
Thanks - no problem in my example code - BUT things to consider: 1) If you are on the blog project, look for the updated React Router link in the description because React Router was updated after this course was released. 2) React is now on React 18 instead of React 17, but this should not have an impact in the code for this course. Nevertheless, it is worth noting.
I am facing the exact same bug, how do I resolve it?
im no begginer but its an helpfull tutorial for all levels
Glad I could help! 💯
when hosting on github pages, what updates do make for the API file URL and fetching in the async? also, great tutorial!
Thank you. The JSON server API we set up is just for our development environment. You cannot host an API on Github Pages. If you complete my Node.js full course for beginners, you will learn to build your own REST API. You can then host it Heroku or Glitch or Repl (and more) for free.
@@DaveGrayTeachesCode is there any other way to host this project without going through that? like with Netlify?
@@shravanp8091 Netlify will host React and other frontend projects, but it does not host backend projects that run on a server - Node.js, PHP, Python, and other backend technologies.
I am building a blog in react aswell and what i ve done,is i ve set up an express server connected to my database to handle data,is it wrong,or is it just an other way?
It is not wrong. It is a great way to do it! This course / playlist just focuses on React so we set up a fake REST API with JSON server instead of building a backend.
@@DaveGrayTeachesCode ok, thanks for the feedback Dave, keep up the awesome work
Sir after I wrote the code for the update posts everything was working fine. But the app won't allow me to create changes in the posts. It says ' failed to load resource'. Is there anything I could have possibly missed?
Yes, you could have missed something. Use diffchecker.com to compare your source code to the source code available in the course resources.
@@DaveGrayTeachesCode sir i checked and i have done everything correctly. Only the Routing part is different in React 18. I think it's an error in my computer or system itself. However, I understood the axios api concept very well. So thank you for the video and the reply!
Hi Dave, I'm researching this, and I have a question since I see you don't address it in the video. I see you are hardcoding "localhost" on the axios.create() function. How do you handle the way the app works in production vs locally? What's the method you use to check if you are running on a deployed version? I've been using the interceptors, but I'm just guessing you can give a much more precise answer and correct way on how to do this. Much appreciated.
Good questions, Daniel! After development, I often switch out "localhost" along with any port number so "localhost:3000" for example - and change it to the actual web address of the REST API I will be using. The routes you use in development - that is the part of the address that comes after the base URL like /posts or /todos or /whatever - those routes should be the same in development that you will use with the actual REST API. To answer your other question, you can check to see if React is in "development" or "production" mode with this value: process.env.NODE_ENV ..use a console.log() statement to check the value in your index.js.
Sir I have a small question... Why did you put setEditTitle, setBodyTitle as dependency for useEffect at 26:58. I don't think it is needed there as that function only has to run at load time
Besides they both are sort of functions to set the values of editTitle and editBody, isn't it? Then their value would never change so why to put them as dependency?
Good question! You are right that they will not change and should not be needed. However an eslinter doesn't recognize this and adding them doesn't harm anything. I think I did it to avoid the warning from an eslinter like this one: "React Hook useEffect has a missing dependency: 'setSomeState'.
Either include it or remove the dependency array.
eslint(react-hooks/exhaustive-deps)"
More discussion on this here: stackoverflow.com/questions/59709304/setstate-in-reacts-useeffect-dependecy-array
@@DaveGrayTeachesCode Okay sir Thank you
Hi Dave. Thank u for this awesome tutorial. I have a doubt, why the useEffect function at EditPost.js is not been called everytime the state of input field changes?
If you put that function (setEditTitle) in the dependencies why this not triggering the useEffect?
Thanks
You're welcome! 💯 React understands that the setState function is not changing. useEffect will only run if the dependencies listed in the dependency array change.
@@DaveGrayTeachesCode Ok, right, but when would setState function change? I understood the changes in post object, but not in functions.
Thanks
@@GilbertoTrin setState won't change, but older versions of React used to give warnings if you didn't include it in the useEffect dependencies. It is not necessary and I think the warnings for setState have been stopped, too.
@@DaveGrayTeachesCode Thanks. Great Job
Is there any way to get to talk to you ? I love the fact that you are one of the few that speaks very clearly. But I have a concept to convey.
You can join my Discord where we discuss all things.
I agree, he's a very good speaker and very clear. If you do C# coding or want to learn I would recommend Tim Corey. He's very good too.
Hi Dave. Thank u for this awesome tutorial. I have a doubt , Can we use axois to fetch data from firebase? I believe we don't need the json server in that case. Please let me know. Thanks.
Yes, JSON server is just for your dev environment. You can use Firebase for the backend of your app in production or a Node JS backend like I show how to build in my Node JS for Beginners course.
@@DaveGrayTeachesCode Thanks Dave. I will try to connect to the firebase DB and update u if I have any issues. Appreciate all ur great efforts. U r the best instructor I have seen so far on TH-cam. May God bless u !!!!
Thanks Dave, you've convinced me to give Axios a try in my current project!
Great! It is a good choice 💯🚀
Great tutorial, many thanks for this. However you seem to be missing the useEffect return and aborting the API calls - I know you want to keep this simple but you didn't mention aborting and possible issues.
Thank you and you are right that I wanted to keep this simple here in a beginners course. The examples you are looking for are here: th-cam.com/video/NqdqnfzOQFE/w-d-xo.html
@@DaveGrayTeachesCode Excellent, thanks for the link Dave, I'll check that out, I noticed in the next video however "custom hooks" you go over the clean up a little. Loving the series!
On 29:08, Dave put handleEdit on the button instead of onSubmit event inside the form element. I tried to put it on the onSubmit event and it worked, the post did change but then after I passed on e.preventDefault(), it stopped working. The console printed something about "uncaught in promise". Anyone care to explain?
At 29:08 - as you noted - I show how to do this. You could create a handleSubmit function above the returned JSX which has both the e.preventDefault() in it as well as the call to handleEdit with the post.id passed in. In this beginners tutorial - I show in the example at 29:08 - how to do this with functions created directly inside the JSX.
@@DaveGrayTeachesCode Alright thank you very much for the explanation
but what about timeouts?
you are a blessing
Thank you, Wilson 🙏🙏
Is this react blog project was a mern project ?
No, I have a separate course for a MERN Stack Project. The projects in this series are just about learning React.
Excellent video
Thank you, Ashhar!
Bro, thank YOU !!!
You're welcome! 💯
just amazing
I followed this video When i'm updating and deleting the user(instead of post ) i'm seeing this error "Failed to load resource: the server responded with a status of 404 (Not Found)" Even i checked in the backend controllers i have used this code in update
export const updateUser = async (req, res) => {
const { id } = req.params;
const { email, first, last, avatar } = req.body;
if (!mongoose.Types.ObjectId.isValid(id)) return res.status(404).send(`No post with id: ${id}`);
const updatedUser = { email, first, last, avatar: id };
await User.findByIdAndUpdate(id, updatedUser, { new: true });
res.json(updatedUser);
}
If the server sends a 404, it is not finding the route and does not reach the code in your controller. It must be something with the route provided.
I just wrote axios.put instead of api.put and get route error, maybe you did something like this. Just check your code again
Thanks sir!
You're welcome!
Thanks a lot
You're welcome! 🚀
Thank you
You're welcome!
thank you sir
You're welcome!
awesome ♥
so no more fetch yaay