I'm using alexa-sdk in Node.js. I have an Alexa skill with 4 different states persisted to DynamoDB. At the end of each interaction, I need the state to change to a READY state. At the end of each handler, I have a SessionEndedRequest where I set my state as follows:
this.state = States.READY;
this.emit(':saveState', true);
When the skill launches with READY state, I jump from state to state using:
this.handler.state = States.COMM;
this.emitWithState('NewSession');
I have NewSession in each handler.
My problem is that the state is not being reset when the user stops using the skill. I need it to go back to READY.
Can someone tell me what I need to do to accomplish that? Thanks.
The code you have here:
this.state = States.READY;
this.emit(':saveState', true);
Won't set the state of Alexa app because the state key exists on the handler object, you will have to do
this.handler.state = States.READY;
this.emit(':saveState', true);
Let me know if this solves your problem. Thanks.
Related
I am changing feature flag value in launch darkly dashboard, the updated flag data is not getting reflect in the application. We need to refresh the application or open in new tab to see the updated results
I recently set this up with React & launch darkly. We did 2 things to achieve this:
subscribe the launch darkly client to changes with on('change')
make those updates trigger a react component re-render (a prop, state, or hook change will do this, the way we did it is through redux)
see the launch darkly documentation here
import * as LDClient from 'launchdarkly-js-client-sdk';
...
// where you initialize the sdk
ldclient = LDClient.initialize(LAUNCH_DARKLY_CLIENT_ID, user);
// set featureFlags in redux when ld client is ready
ldclient.on('ready', () => {
const flags = ldclient.allFlags(); // get the flags
dispatch(actions.setFeatureFlags(flags)); // store them in redux
});
// *the part you're asking about*
// on('change') to subscribe to flag changes
ldclient.on('change', () => {
// you could listen for the specific flag change, but can also just grab all flags whenever there is a change
const flags = ldclient.allFlags();
dispatch(actions.setFeatureFlags(flags));
});
From there, your components can connect to redux, and when the flags get updated in redux, your components will be passed the new flag props which triggers a re-render.
The same idea can work if you replace redux with some other method that passes the flag props/state to components.
I am learning react-redux at the moment, already grasped the basics (I believe), I am now trying to create a notification array on my state that can be populated by several actions.
But since is a notification, I only want to add a notification after each of those actions is completed (the state is changed).
I thought about using a middleware class but that would add the notification into array before the action is computed on the reduce.
Quick example:
User logins -> dispatch action -> affects state property related to login -> adds a notification on the notification array
User adds item -> dispatch action -> affects state property related to items -> adds a notification on the notification array
These are 2 different actions, I could in the if logic of each action (on reducer) update the notification array, but seems like repeated code and I would be creating notification object on a reducer, is that okay?
So in this case where should I dispatch the action of adding a notification to the notification array?
I am looking for best practices
The best practice is to handle such scenario's in reducer. Process the data one-time and update state accordingly. In your scenario, you want to update the notifications array once the action is completed. You have to do that repeatedly because it is to be done. Here is what you can do:
case LOGIN:
//checks if user is valid
return {
...state
loggedIn: true,
user,
notifications: state.notification.push({ id: 1, message: "Logged In!" })
}
And if you want to remove a notification you can do that:
case REMOVE_NOTIFICATION:
// You can get the notification ID you want to remove from action
let notifications = state.notification.filter(notify => notify.id !== action.id);
return {
...state
notifications
}
Hope this will help you.
I'm working on a modal component where users can edit the contents of a post they created.
I have it set up where a notification window pops up if the user tries to close the modal without saving.
However, sometimes users don't make any changes and I don't want them to see this notification, I just want the modal to close.
I could create separate states to store the original state then compare those states to the current states, but I have a lot of states (15) and that seems messy.
I'm wondering if there is a way for me to check if any set of particular states have been changed at all? That way, I would know to show the notification or not.
It seems that you use hooks, so in your case I would suggest to refactor a little bit your component with the states like below and after this has been done to use the JSON.stringify to check if something has been changed. You will actually have one state as an object.
const [var1, setVar1] = useState($initialVar1);
const [var2, setVar2] = useState($initialVar2);
const [var3, setVar3] = useState($initialVar3);
...
const [var14, setVar14] = useState($initialVar14);
to
const [componentState, setComponentState] = useState({
var1: $initialVar1,
var2: $initialVar2,
var3: $initialVar3
...
})
Wherever you want to update the individual states you can use the spread operator
setComponentState({
...componentState,
varX: newValue
})
I'm working on app based react+mobx and as backend use the firebase.
Currently on the app start i need to check if user is logged in.
I'm doing it with firebase.auth().onAuthStateChange listener, but because it's async function - the first response always null.
So my current solution is display some loading message and put setInterval function with status checking in componentWillMount lifehook.
The question is - is there any more elegant solution to this issue?
Before you call firebase.auth().onAuthStateChange, modify your state to be something like: state.authenticatedUser: 'pending'. Have your observer change that state to real user info once it is called.
Have your components take into account state.authenticatedUser when rendering and render either "authentication pending" or "authenticate user"
There is a plenty of discussion on how to communicate with external services in Flux.
It is pretty clear that the basic workflow is to fire an HTTP request, which will eventually dispatch successful or failure action based on the response. You can also optionally dispatch "in progress" action before making the request.
But what if request's parameters depend on store's state? Nobody seems to mention it.
So essentially, based on user interaction with the view, an ACTION is dispatched. Store owns logic on how to transition from current state0 to the next state1 given ACTION. Data from state1 is needed to properly form new HTTP request.
For example, user chooses a new filter on the page, and store decides to also reset pagination. This should lead to a new HTTP request with (new filter value, first page), not (new filter value, current page from state0).
View can not make the HTTP call itself right with user's interaction because it then would have to duplicate store's logic to transition to the next state.
View can not make the HTTP call in its store's onChange handler because at this point it is no longer known what was the origin of the state change.
It looks like a viable option to make store fire the HTTP request in the action handler, after it transitioned to the next state. But this will make this action implicitly initiating HTTP call, which disables neat possibility to have a replayable log of dispatched actions for debugging.
Where should HTTP requests be initiated in Flux?
Let's start at the bottom:
It looks like a viable option to make store fire the HTTP request in the action handler, after it transitioned to the next state. But this will make this action implicitly initiating HTTP call, which disables neat possibility to have a replayable log of dispatched actions for debugging.
This can be mitigated by not initiating HTTP requests if you're in debugging/replay mode. This works great as long as the only thing you do in your HTTP request handlers is fire actions (e.g. SUCCESS and FAILURE actions). You could implement this with a simple global boolean (if (!debug) { httpReq(...) }), but you could also make the pattern a bit more formal.
In Event Sourcing parlance, you use Gateways for such purposes. In normal operation, the Gateway makes your HTTP requests, and in debugging, you turn the Gateway off (so it doesn't make any HTTP requests).
That said, I think the problem can actually be solved by rethinking where your HTTP requests are made.
So essentially, based on user interaction with the view, an ACTION is dispatched. Store owns logic on how to transition from current state0 to the next state1 given ACTION. Data from state1 is needed to properly form new HTTP request.
In the second link in your question (Where should ajax request be made in Flux app?), I recommend doing your writes in action creators but reads in the stores. If you extrapolate that pattern into your use case, you might end up with something like this (pseudocode and long variable names for clarity):
class DataTable extends React.Component {
render() {
// Assuming that the store for the data table contains two sets of data:
// one for the filter selection and one for the pagination.
// I'll assume they're passed as props here; this also assumes that
// this component is somehow re-rendered when the store changes.
var filter = this.props.filter;
var start = this.props.start;
var end = this.props.end;
var data = this.props.dataTableStore.getDataForPageAndFilter(
start, end, filter
);
// the store will either give us the LOADING_TOKEN,
// which indicates that the data is still loading,
// or it will give us the loaded data
if (data === DataTableStore.LOADING_TOKEN) {
return this.renderLoading();
} else {
return this.renderData(data);
}
}
}
class DataTableStore {
constructor() {
this.cache = {};
this.filter = null;
this.start = 0;
this.end = 10;
}
getDataForPageAndFilter(start, end, filter) {
var url = HttpApiGateway.urlForPageAndFilter(start, end, filter);
// in a better implementation, the HttpApiGateway
// might do the caching automatically, rather than
// making the store keep the cache
if (!this.cache[url]) {
this.cache[url] = DataTableStore.LOADING_TOKEN;
HttpApiGateway.query(url)
.then((response) => {
// success
var payload = {
url: url,
data: response.body
};
dispatch(DATA_FETCH_SUCCESS, payload);
}, (error) => {
// error
dispatch(DATA_FETCH_FAIL, { ... });
});
}
return this.cache[url];
}
handleChangeFilterAction(action) {
this.filter = action.payload.filter;
// the store also decides to reset pagination
this.start = 0;
this.end = 10;
this.emit("change");
}
handleDataFetchSuccessAction(action) {
this.cache[action.payload.url] = data;
this.emit("change");
}
handleDataFetchFailAction(action) {
// ...
}
}
DataTableStore.LOADING_TOKEN = "LOADING"; // some unique value; Symbols work well
You can see that the store is responsible for deciding how to update the pagination and the filter variables, but is not responsible for deciding when HTTP requests should be made. Instead, the view simply requests some data, and if the store doesn't have it in the cache, it will then make the HTTP request.
This also allows the view to pass in any additional local state into the getter (in case the HTTP requests also depends on local state).
I'm not sure to understand all the parts of the question but will try to answer with some useful insights.
Flux is a bit like a not-yet mature version of EventSourcing / CQRS / Domain-Driven-Design for frontend developers
We use something akin to Flux for years on the backend with a different terminology. We can compare Flux ActionCreators to DDD Commands, and Flux Actions to DDD Events.
A command represent the user intent (LOAD_TIMELINE(filters)). It can be accepted or rejected by a command handler that will eventually publish some events. In an UI this does not make much sens to reject commands as you don't want to display buttons that the user should not click...
An event represent something that has happened (always in the past).
The React app state that drives the UI is then somehow a projection of the event log to a json state. Nothing can be displayed on the UI without an event being fired first.
Answering your questions
But what if request's parameters depend on store's state? Nobody seems
to mention it.
In DDD, command handlers can actually be stateful. They can use the app state to know how to handle the command appropriately. Somehow this means that your Flux ActionBuilders can be stateful too (maybe they can use some store data while )
So essentially, based on user interaction with the view, an ACTION is
dispatched. Store owns logic on how to transition from current state0
to the next state1 given ACTION. Data from state1 is needed to
properly form new HTTP request.
In DDD there is a concept called Saga (or Process Manager).
To make it simple, it receives the event stream and can produce new commands.
So basically you can express through a Saga your requirement: when there's an event "FILTERS_UPDATED", fire a command "RELOAD_LIST" with the new filters. I'm pretty sure you can implement something similar with any Flux implementation.
Sagas should rather be disabled when you replay the event log, as replaying the event log should not have side effects like triggering new events.
These kinds of semantics are supported in my Atom-React framework, where stores can act as stateful command handlers or sagas.