Before writing too much code, I thought I'd conceptually understand whether what I am doing is correct.
I have some components, that import a mixin. The mixin has a web api call to retrieve the some links from the (HATEOAS) API, so the UI can use the links without forming its own links. These would look something like:
[
{
"Rel": "GetSupportingData",
"Href": "https://api.com/SupportingData"
},
{
"Rel": "Search",
"Href": "https://api.com/Search"
}
]
So the MIXIN has a method called GetLink("Search") that would retrieve the links from the API and return the link requested.
This is all ok, but as the mixin is imported to a lot of components, I don't want each time its used to make the WEB API call to get the links before filtering them. I was therefore wondering if I should use Vuex to manage the state of the links and retrieve them if the store count was zero?
The examples of Vuex I have seen instantiate it on the component, so what I'm doing feels like it may not be correct.
You can store the web api links to store that is one approach, but when you refresh the page again the store needs to be filled with the api links
So, the alternate approach is to use localStorage or indexedDB of browser
Everytime when you load the application first it goes to localstorage or indexedDB and checks for the api links. If its present, it restores to Vues store. Or calling mixin method to fetch api links and loads to browser storage and vuex store
Related
As far as I know asyncData function in NuxtJs pages is rendered in Server-side before creating the component. And also when user navigates between pages internally after page load. fetch function is very similar but we can set data to store inside it and check if data exist in store on route change...
Now the question is why would I want to send a request to an API in both page refresh and route change? Isn't it better to use fetch function and store data in vuex store so there is no need for further API calls? what kind of data is needed to get fetched inside asyncData function?
For example, if I want to show a list of posts in a server-side rendered app, I think the best way is to use fetch property to populate the vuex store and after that, in every route change I will have the data inside the store and there is no need for API call.
The use case is for retrieving data that is only relevant to a specific page.
For example, you have several endpoints that return data about specific animals, /api/cats, /api/dogs, /api/birds.
When you load theapp.com/cats in your browser, the asyncData function fetches the data from /api/cats and renders it server-side.
Similarly, for theapp.com/dogs, it fetches /api/dogs.
The use-case changes if there is an /api/animals endpoint that contains ALL the animal data in one feed (dogs, cats and birds).
In this case, you would do the retrieval once to populate the store with all page data with something like nuxtServerInit
I am sorry if this question has already been asked, but i can't seem to find a clear explanation for my problem.
Problem: i have a web page showing a client's problem. This page need data like client ID or problem number to display it in different parts of the page (header, menu, body). This data is obtained with axios calls.
So i have multiple components which need the same data from the same axios call.
I can't understand how it is possible to make one axios call, for client ID for example, and share it with multiple components instead of making an axios call each time i need the data.
Are mixins a solution?
I have tried to use a mixin:
Vue.axiosGet({
methods: {
request: function(url) {
return axios.get(url).then(response => {
return response.data;
});
}
}
});
But now i don't know where or how to store the data i'll get.
EDIT: i forgot to precise that i don't want to use VueX.
You say that you don't want to use Vuex, but why not? I would recommend you use the Vuex store to achieve what you're looking for. A vuex store will cache/hold information in it, meaning that you can easily access it on a different page. Vuex would solve your problem and allow you make a call once, and later access the data. No need to re-invent the wheel, it's an effective way to achieve what you need.
If you really don't wanna use Vuex, there're always solutions like nedb, but I'd strongly recommend Vuex.
I've got a small Vue/Vuex/Rails app that I'm building and am trying to figure out the best way to handle this scenario.
Upon login or page refresh, I have a mixin that checks to see whether currentUser is in state. If it's not, it runs a call to my api to retrieve the currentUser, as well as that user's deeply nested relationships. Something like this:
currentUser: {
...user data
groups: [
categories: [
items: [
...item data
]
],
],
}
That api call lives in user.module.js. My question is, rather than storing the entire user object with all of its nested data in user state, is it possible to split out all of that data into separate modules (eg.: groups.module.js, categories.module.js, items.module.js)?
This would allow me to make a much simpler action and mutation by going straight to item in the items.module.js.
I appreciate any help!
Yes, definitely you should split them in multiple modules, otherwise, your data structure will get really difficult to deal and understand. After you have defined how will be structured your modules, when you get the user data you can dispatch as many actions you need to each module to populate their states.
I created a codepen to show you.
I have a vue3-app that serves as the frontend of an asp.net core 2 api.
Much of the requested data gets used by multiple components. And in order not to make multiple identical requests, i want to store the response-data in my vuex-store if it's not in there already.
The problem is, that most of that data changes a lot, so i need to be able to tell vuex to refresh the data after some time.
But i don't want to refresh all of the requested data, since some of it doesn't need to be refreshed as often and some not at all (for example a list of countries).
So what I need is a way to tell vuex wheter i want to save the response of a specific axios request forever, or to re-request it after a set amount of time.
My questions are: Is there a plugin for this that I couldn't find? And if not, how could i implement the described functionality without rewriting it for every request?
There are some axios cache projects available:
axios-extensions (LRUCache)
axios-cache-adapter (localforage)
cachios (node-cache)
The 2 most popular currently are axios-extensions and axios-cache-adapter
Source of the chart
There is a library axios-cache-adapter that is a plugin for axios, to allow caching responses.
It is a great solution for implementing caching layer that takes care of validating cache outside of application's data storage logic and leverages it to requets library instead.
It can be used with both localstorage and indexedDB (via localforage library)
im building a specific book reader like app.
Main page call api/booksList and receive the json array containing each book info like:
[ { id: server_db_id, title: "title test", sum: 10 , date: ... }
]
ans its cached after the request, so im not saving the book list into indexedDB, localStorage or other storage. If i need one specific book, i just call the api book list again and filter it. Is that bad design? (book will be over 200 items)
Whe user open the book, it call the /api/book/book_id and its cached too, the opened book response is a json list of the lines of the book, eg:
[
{
id: ...
content: "This is line...lore ipsum..."
....
}
]
I put the api response inside vue data variable and the component is rendered correclty
Im not using any kind of handler for keeping this offline by my hand. To detect if user already opened this book, i just call the api, check if errors happened or the responde body has content.
Is that a wrong, bad or stupid decision? Will this hit the quota limit api or other kind of limitation? The "gods" of pwa will raise the finger to me and say: WAAAT. (im not using indexedDB at first because it need some models handling and i want to make things easier if possible)
I my self was just researching this and concluded, at the moment I am going to go with this method, where I use cache for assets, js, css, html etc based on their matching routes.
Then when it comes to data e.g. json requests etc. Its best to store them in indexedDB (or an equivalent), which really does not require a model or schema as such.
See Jake Archibald's IndexedDB-Promise library https://github.com/jakearchibald/idb its really simple to get your head round.
Though both Jake and Addy say it's not a defacto rule, so you can decide ultimately what is best for you.
Read this for better clarification
https://developers.google.com/web/ilt/pwa/live-data-in-the-service-worker
https://medium.com/dev-channel/offline-storage-for-progressive-web-apps-70d52695513c
It helped me to make a better decision on how to go about moving forward.
Recommendations Also
Check out PWA Training: https://developers.google.com/web/ilt/pwa
Workbox: https://developers.google.com/web/tools/workbox (This has sped up my development massively!)
Codelabs: https://codelabs.developers.google.com/ (Search PWA)
The guides on here are really good at taking you through everything you need.
Good Luck with your PWA
Random thought (edit)
One thing that makes me question this though is based on some of the examples and guides I have seen is that, data storage is handled in a more ad-hoc manner. For example, if the PWA calls out an API, there are two methods I have come across where you can either manage cached data in the application or in the service worker, e.g. if your API calls to get JSON fails in the app, it can revert to getting data in the indexedDB which hopefully was pre-cached the first time your app called the API.
Or you can use self.addEventListener('fetch', (event) => { ad-hoc stuff here }) this is where you can match either an asset, or data request and hijack the response with either a cache or indexedDB response. Which prevents the need handle offline data in your app.
The first method makes me feel uneasy so i'm gonna go with the addEventListener approach both in the service worker cause thats what it is there for plus my app does not then have to worry about that.