Is possible get which component call some action Vuex? - vue.js

Is possible to get which component call some action Vuex ?
I return a promise from vuex actions and take some decisions in component as set errors messages on respective fields but I would like to set on component.$validator.errors asap I receive http response (in action method)
Is that possible and a good approach ?

In Vuex when you make a call to a mutation or action you can send an object alongside your dispatch call, if you wanted to track the component which called an action you could also send that as part of the object. Better yet you could have all objects sent via Vuex extend a specific class if your using typescript. Though note that finding which component called an action or mutation is not native behavior for Vuex.
Consider the following:
try{
let out = await this.$store.dispatch('someActionHandler', {referingComponent: this.$options.name, someParam:[1,2,3]})
} catch (e){
// Lets deal with the problem
}
In here we are sending the name of the component as a parameter, so it can be checked inside our action handler or alternatively you could just pass this straight to a mutation, though I think the former is a more likely case if you plan to build logic into this.
As for if this is a good approach, the answer to that is fairly subjective, I personally don't see any problems with the above approach. Though I would think it was an anti pattern if the majority of components are never checked or the added data ends up becoming meaningless fluff passed alongside every call.

Related

How to keep component in sync with AsyncStorage?

So I need to get a value from async storage to build my component UI and no problem with that. But, in another component I'll be changing this async storage value, but once I do it, I need the other component to re render and get the updated value from async storage.
I know that this can be done in react web using local storage but that's just possible because local storage provides an event listener which fires whenever it changes, but there is no way to attach an event listener to async storage.
So my question is, is this even possible to do? And if not, any suggestions on how to get this done?
I haven't worked with async storage, but typically you will use the observer pattern through a library like RxJS in Javascript.
Basically you create an observable to which you subscribe, and subsequently the observer gets notified of state updates to the observable.
You can check out the source code of this library that I just found for an example:
https://github.com/bassihassan/xreactive-react-native-storage/blob/master/index.js

Redux saga: How can i make sure only my saga is able to update a certain state?

I have a mobile app made in React Native, and I've just run into a best practice dilemma i've encountered many times while using Redux/Redux Saga. I would love if i could get someone else's thoughts on this.
For a new piece of functionality i'm implementing, i need to be able to tell how many times the app has been launched. This involves asynchronously retrieving how many times the app was previously launched from the device storage. If there's a new launch happening, i also need to add +1 to the number and store that in the device storage.
This is how i currently do it:
Dispatch appLaunched() action when app launches.
Redux Saga takes event.
Inside Saga: Retrieve how many times app was previously launched (appLaunchCount) from device storage (wait for async to finish).
Add +1 to previous appLaunchCount.
Store new appLaunchCount in device storage (wait for async to finish).
Dispatch put() with new appLaunchCount to reducer.
Update state with new appLaunchCount inside reducer.
My problem with this method is step 6. Technically any part of my app could dispatch a new app launch count to my reducer, with any integer, and the reducer would update the state just the same even though it didn't come from the saga.
My question is this: How can i protect my Reducers/Sagas/Actions so that only my saga can dispatch the action with the current appLaunchCount ?
P.S The only solution i can think of is writing my saga and reducer in the same file, and use private actions that only the saga and reducer can access. I would really hate to have to keep all that code together though.
Private actions aren't really a thing. The store is, by design, a global object. And since actions are just objects with a type property, anyone who can construct an action object of the right type can in principle dispatch an action and kick off your reducer.
What you could do is make the action have a type that makes it obvious that it's meant to be private. For example, maybe the action looks like:
{
type: '__PRIVATE_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__'
// You could tone it down a bit from this :)
}
That of course doesn't make it actually private, but at least if someone wants to use it, it's impossible for them to not realize your intent.
If you wanted to make it more secure, perhaps you could use a symbol as the type, and therefore only anyone with access to the symbol could construct the right action. For example:
const appLaunchCount = Symbol('appLaunchCount');
// action would look like:
{
type: appLaunchCount
}
But then the issue is making sure that symbol stays hidden, and can be accessed only by those who you want to access it. Similar to one of the things you mentioned, if you have the saga/reducer in the same file, then you could make sure that other files couldn't access this symbol; but once you start exporting it it becomes harder to control.

What is a difference between action,reducer and store in redux?

I am new to react/redux. I am trying to figure out how all the pieces in redux interact. The one thing giving me trouble is understanding the relation between actions and reducers,store.
It's pretty simple when you think about it:
Store - Is what holds all the data your application uses.
Reducer - is what manipulates that data when it recieves an action.
Action - is what tells reducer to manipulate the store data, it carries the name and (not required) some data.
Reducer is usually in a format of a switch statement, that switches between all possible Actions (Cases) and then manipulates the Store data based on action. When a reducer data changes within the redux, the properties in your components are changed and then the re-render ocurrs.
Store -> A Globalized state
Action -> What you wanna do, eg: event click
Reducer -> Describes how your action transfers state into the next state.
It checks which action took place and based on the action it updates the store.
Dispatch -> Way how we execute the action. eg: Dispatch the action to the reducer. Then reducer will check what to do and the store gets updated.
Store
An Object that holds the applications state data
Reducer
A function that returns some state data. Is triggered by an action type
Action
An object that tells the reducer how to change the state. It must contain a type property. It can optionally contain a payload property
The actions, reducers and stores are the three building blocks of redux.
Actions: Actions are the only source of information for the store. Actions have a type field that tells what kind of action to perform and all other fields contain information or data. And there is one other term called Action Creators, these are the function that creates actions. So actions are the information (Objects) and action creator are functions that return these actions.
Reducers: As we already know, actions only tell what to do, but they don’t tell how to do, so reducers are the pure functions that take the current state and action and return the new state and tell the store how to do.
Store: The store is the object which holds the state of the application.
I found this link to be particularly helpful - https://www.geeksforgeeks.org/introduction-to-redux-action-reducers-and-store/
Imagine a situation where you want your class based components to share data among each other. They may even bring changes to the data. One may provide data to others in the form of props. But it very difficult to keep track of the name of the props and the structure of data.
The Store actually simplifies this stuff. You set up your application architecture in such a way that the components will get their data from the supply what is known as the Store. Actually, the mechanism is so smart the component will re-render itself when the data changes since the components are all ears.
And Actions are nothing but the carriers of data from your application to the store.
And it is very difficult to articulate the concept of reducers. You may imagine a real store where one puts different stuff for future use. The store is of no use when the stuff is put haphazardly. One may spend hours inside but may not find anything. The Reducers in simple terms manage the way data is kept in store provided by the actions.
according to redux documents:
store: The whole global state of your app is stored in an object called store.
dispatcher: To change something in the state, you need to dispatch an action. (and that is what dispatcher does)
action: An action is a plain JavaScript object that describes the kind of change to make (as dictated by action.type) to the store and the relevant payload required for that change.
reducer: to tie state and actions together, we write a function
called a reducer. it’s just a (pure) function that takes state and action as arguments and returns the next state of the app.
for a deeper understanding look at the diagram in this link.
Actions: Actions are a plain JavaScript object that contains information. Actions are the only source of information for the store. Actions have a type field that tells what kind of action to perform and all other fields contain information or data.
Example :
function addTask(task) {
return {
type: 'ADD_TODO',
task: task
}
}
Reducers: As we already know, actions only tell what to do, but they don’t tell how to do, so reducers are the pure functions that take the current state and action and return the new state and tell the store how to do.
Example:
function task(tasks = [], action) {
if (action.type === 'ADD_TODO') {
return [...tasks, action.task];
} else if (action.type === 'REMOVE_TODO') {
return tasks.filter(task => task !== action.task);
}
return tasks;
}
Store: The store is the object which holds the state of the application.
ref: https://www.geeksforgeeks.org/introduction-to-redux-action-reducers-and-store/

Computed property depending on two async computations in Vue.js

I have a component that at creation fires two requests to a RESTful server. Responses are then stored in the Vue Store appropriately.
This component has a computed property that depends on both responses.
But, as designed, any relevant change in the store triggers recomputation of the property and all the consequent updates, for example in the related template.
How would I indicate that the property in fact did not change if only one of the required responses is received and there is no need to do any updates?
The post is from quite a while ago but I was running into the same problem. I have not tried this yet but I believe this to be the solution for this problem:
https://vuex.vuejs.org/en/actions.html#composing-actions
Especially the last part with the async/await example. It makes it clear how you can perform a mutation with multiple async actions.

Flux without data caching?

Almost all examples of flux involve data cache on the client side however I don't think I would be able to do this for a lot of my application.
In the system I am thinking about using React/Flux, a single user can have 100's of thousands of the main piece of data we store (and 1 record probably has at least 75 data properties). Caching this much data on the client side seems like a bad idea and probably makes things more complex.
If I were not using Flux, I would just have a ORM like system that can talk to a REST API in which case a request like userRepository.getById(123) would always hit the API regardless if I requested that data in the last page. My idea is to just have the store have these methods.
Does Flux consider it bad that if I were to make request for data, that it always hit the API and never pulls data from a local cache instance? Can I use Flux in a way were a majority of the data retrieval requests are always going to hit an API?
The closest you can sanely get to no caching is to reset any store state to null or [] when an action requesting new data comes in. If you do this you must emit a change event, or else you invite race conditions.
As an alternative to flux, you can simply use promises and a simple mixin with an api to modify state. For example, with bluebird:
var promiseStateMixin = {
thenSetState: function(updates, initialUpdates){
// promisify setState
var setState = this.setState.bind(this);
var setStateP = function(changes){
return new Promise(function(resolve){
setState(changes, resolve);
});
};
// if we have initial updates, apply them and ensure the state change happens
return Promise.resolve(initialUpdates ? setStateP(initialUpdates) : null)
// wait for our main updates to resolve
.then(Promise.params(updates))
// apply our unwrapped updates
.then(function(updates){
return setStateP(updates);
}).bind(this);
}
};
And in your components:
handleRefreshClick: function(){
this.thenSetState(
// users is Promise<User[]>
{users: Api.Users.getAll(), loading: false},
// we can't do our own setState due to unlikely race conditions
// instead we supply our own here, but don't worry, the
// getAll request is already running
// this argument is optional
{users: [], loading: true}
).catch(function(error){
// the rejection reason for our getUsers promise
// `this` is our component instance here
error.users
});
}
Of course this doesn't prevent you from using flux when/where it makes sense in your application. For example, react-router is used in many many react projects, and it uses flux internally. React and related libraries/patters are designed to only help where desired, and never control how you write each component.
I think the biggest advantage of using Flux in this situation is that the rest of your app doesn't have to care that data is never cached, or that you're using a specific ORM system. As far as your components are concerned, data lives in stores, and data can be changed via actions. Your actions or stores can choose to always go to the API for data or cache some parts locally, but you still win by encapsulating this magic.