How to schedule catched task in another zone?
Assume I want to schedule all setInterval`s in root zone.
It`s not working:
Zone.current.fork({
name: "Chiled_zone",
onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) {
if (task.source === "setInterval")
return parentZoneDelegate.scheduleTask(Zone.root, task);
else
return parentZoneDelegate.scheduleTask(targetZone, task);
}
})
.run(() => {...});
It`s not working too:
Zone.current.fork({
name: "Chiled_zone",
onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) {
Zone.root.scheduleTask(task);
}
})
.run(() => {...});
Could you tell me about your use case? And yes you can schedule the task in a different zone.
Zone.current.fork({
name: 'child zone',
onScheduleTask(parentDelegate, currentZone, targetZone, task) {
task.cancelScheduleRequest();
return Zone.root.scheduleTask(task);
}
})
Related
I am performing an authentication module where I when I click the sign in button , I am verifying user present is MySQL db or not . I am dispatching the function in here in sign in page
Basically when I dispatch it , the null state of the rSignedIn is not changed immediately after dispatch function. I am completely using react hooks. Please help me solve this , I have been trying this for three days.
But the rSignedIn state value updates when I click the login button again, in general , the when I use the state value using the useSelector the value is updated the second the time when the handleLogin() is invoked
//Sign in Page
...
...
const status=useSelector((state)=>state);
...
...
const handleLogin=(event)=>{
dispatch(LoginUser(loginData));
console.log(status.auth.rSignedIn);
if(status.auth.rSignedIn){
console.log("LOGIN success");
History.push('/');
}else{
console.log("LoginFailed") ;
}
}
this is the action index page where I sent a request to MySQL db , then if there is a response I am dispatching it else an error.
export const LoginUser=(loginData)=>async(dispatch)=>{
await mysqlDB.post('/fetch/retreive',loginData)
.then((response)=>dispatch({type:ActionTypes.LOGIN_SUCCESS,payload:response.data}))
.catch((error)=>dispatch({type:ActionTypes.LOGIN_FAILED}))
}
This is my Reducer for this :
const initialState = {
gSignedIn:null,
userId:null,
registered:null,
data:null,
rSignedIn:null,
}
export default (state=initialState,action)=>{
switch (action.type){
case ActionTypes.GSIGN_IN:
return {...state,gSignedIn:true,userId: action.payload};
case ActionTypes.GSIGN_OUT:
return {...state,gSignedIn:false,userId:null};
case ActionTypes.REGISTER_SUCCESS:
return {...state,registered:true,data: action.payload};
case ActionTypes.REGISTER_FAILED:
return {...state,registered:false,data:null};
case ActionTypes.LOGIN_SUCCESS:
return {...state,rSignedIn:true,data: action.payload};
case ActionTypes.LOGIN_FAILED:
return {...state,rSignedIn:false,data:null};
case ActionTypes.LOGOUT:
return {...state,rSignedIn:false,data:null};
default:
return state;
}
};
dispatch will not update your state value immediately. State value is bound by closure and will only update in your next render cycle.
You can either use history.push within your action or make use of useEffect
const handleLogin=(event)=>{
dispatch(LoginUser(loginData, History));
}
...
export const LoginUser=(loginData, history)=>async(dispatch)=>{
await mysqlDB.post('/fetch/retreive',loginData)
.then((response)=>{
dispatch({type:ActionTypes.LOGIN_SUCCESS,payload:response.data}));
history.push('/')
}
.catch((error)=>{
dispatch({type:ActionTypes.LOGIN_FAILED}))
}
}
With the useEffect, you need to run the it only on change and not on initial render
const initialRender = useRef(true);
useEffect(() => {
if(!initialRender.current) {
if(state.auth.rSignedIn) {
history.push('/');
} else {
console.log(not signed in);
}
} else {
initialRender.current = false;
}
}, [state.auth.rSignedIn])
I just confuse with this case. I've been try to make sure the time zone in MySql and see the data that out from Date(Date.now()). That's all is correct with my timezone. But when i try to input the data to MySql, and i check in my Database. The time zone is wrong and different with my Time zone. Is there anyone can help me ?
This my code
const Employee = require('../models/employee');
const History = require('../models/history');
async createHistory(employee){
let result;
try {
const checkData = await Employee.findOne({where :
{employeeId : employee.employeeId}
});
if(checkData !== null){
const createData = await History.create({
employeeId : employee.employeeId,
in : Date(Date.now())
});
console.log(date.toLocaleString());
console.log('True')
}else {
result = {message : false}
}
} catch (e) {
logEvent.emit('APP_ERROR',{
logTitle: '[CREATE-HISTORY-ERROR]',
logMessage: e
});
}
return result;
}
The Time in field 'in' is wrong, it should be 14:43
I just get the answer,
The answer is .. because i using Sequelize to store the data to MySql i have to input the time zone in my connection.
Here my code :
const connection = new Sequelize(
{
timezone: "+07:00"
}
);
I am using Vue 3.9.3, along with highcharts-vue 1.3.5 . I am trying to put into an object each highchart, as it loads, so then I have access to any chart I want like
myCharts.aChart or
myCharts.anotherChart,
so I can easily do myCharts.anotherChart.addData
In practice I do,
<highcharts :constructor-type="'stockChart'" :options="options" :callback="chartcallback" ></highcharts>
and then
data(){
return{
charts:{}
}
},
methods:{
chartcallback(hc){
let obj = {[hc.options.id] : hc};
this.charts = Object.assign(this.charts, obj);
//also tried this
const newChart = {id:hc.options.id, chart : hc};
this.$set(this.charts, newChart.id, newChart);
//also tried this
this.charts = Object.assign({}, this.charts, {
[hc.options.id] : hc
});
//also tried this
this.charts[hc.options.id]= hc;
console.log('test ', this.charts);
}
}
and then I would watch my data and each time they change, I would add data to each highchart,
watch: {
myData: {
immediate: true,
deep: true,
handler(){
this.charts.NameChart.series[0].setData(this.myData[0], true);
this.charts.DrinkChart.series[0].setData(this.myData[1], true);
//etc....
this.charts.NameChart or this.charts.DrinkChart should be constructed in chartcallback and NameChart, DrinkChart is the value of hc.options.id hc.options.id always has a value and it is there, I checked.
The problem is
at the end of chartcallback where I do console.log('test ', this.charts);, the produced obj is
//first time
{NameChart:chart}
//second time
{NameChart:chart}
but it should be
//first time
{NameChart:chart}
//second time
{NameChart:chart,
DrinkChart:chart}
It looks like it overwrites the this.charts every time chartcallback is called. I tried several methods, as I note, but nothing works.
What can I do ?
Thanks
i'm new in angular 6 and ngrx store. I try to dispatch action after get data subscribe from store but it make infinite loop and crash browser? What i was wrong . Some solution i find it using do/tap operator of rxjs but still not working. And when i use {{(feedState | async).loading}} for example , it alway return undefined .
my component:
ngOnInit() {
this.store.dispatch(new FeedActions.GetFeedCategories());
this.feedSubscription = this.store
.pipe(
select('feed'),
map(data => {
this.feedState = data;
return data.categories;
}),
tap(data =>
this.store.dispatch(
new FeedActions.GetFeedItems({
cat_id: data[this.selectedIndex],
page: 0
})
)
)
)
.subscribe(data => {});
}
The select operator will create an observable which emits every time the state of 'feed' is updated. This will fire the first time when you do your FeedActions.GetFeedCategories() but it will also fire again when the result of FeedActions.GetFeedItems(...) is added to the state, which will cause FeedActions.GetFeedItmes(...) to be executed again, and again, and again...
The simple solution is to add a take(1) into the pipe, so you only get a single fire of the map and tap operators:
ngOnInit() {
this.store.dispatch(new FeedActions.GetFeedCategories());
this.feedSubscription = this.store
.pipe(
select('feed'),
take(1),
map(data => {
this.feedState = data;
return data.categories;
}),
tap(data =>
this.store.dispatch(
new FeedActions.GetFeedItems({
cat_id: data[this.selectedIndex],
page: 0
})
)
)
)
.subscribe(data => {});
}
However, it may be worth considering splitting the concerns here - you've mixed the job of preparing the state with the job of selecting the state for display. A better solution may be something like this:
ngOnInit() {
this.store.dispatch(new FeedActions.GetFeedCategories());
this.store.pipe(
select('feed'),
take(1),
map(data => data.categories),
tap(data =>
this.store.dispatch(
new FeedActions.GetFeedItems({
cat_id: data[this.selectedIndex],
page: 0
})
)
)
)
.subscribe(() => {});
this.feedState = this.store.pipe(
select('feed')
);
}
... then in your template, you can use {{feedState | async}}?.loading or whatever as needed.
The async pipe does the subscription for you and expects an observable, not a raw data field. In your example, this.feedState should be of type Observable<FeedState>, but it looks to be a raw data type (e.g. FeedState instead of Observable) from the code provided.
I am using Redux spread operator to hopefully mantain the state as immutable objects.
However, i am managing to make the most simple unit test fail.
I assume the error probably has to do with immutables, but am i not using the spread operator correctly?
Here is my unit test:
describe('app logic', () => {
it('initialises app', () => {
const newState = reducer(INITIAL_STATE, {type: "NEXT"})
const expectState = {
start: true,
render_component: null,
requests: {},
results: {},
}
console.log('newState', newState)
console.log('expected state', expectState)
expect(newState).to.equal(expectState)
})
})
and here is my reducer
export const INITIAL_STATE = {
start: false,
render_component: null,
requests: {},
results: {}
}
export const next = (state) => {
if (state === INITIAL_STATE) {
return {
...state,
start: true,
}
}
return state
}
export function reducer(state = INITIAL_STATE, action) {
switch (action.type) {
case 'NEXT':
return next(state)
default:
return state
}
}
I print the two objects, and they look the same.
i get the error :
1) app logic initialises app:
AssertionError: expected { Object (start, render_component, ...) } to equal { Object (start, render_component, ...) }
Not sure exactly which testing library you are using, but usually a name like .equal is used to test strict equality ( === ), which means (at least in the case of objects) that the two things being compared must actually reference the exact same object. So, for example,
const original = { a: 1 }; // creates a new object, assign it
const testMe = { a: 1 }; // creates another new object, assign it
console.log( original === testMe ) // false
evaluates to false, because while the objects have the same content, they do not reference the exact same object. They are separate, independently created, objects that happen to have the same content. Compare that to
const original = {a: 1}; // create a new object
const testMe = original; // create another reference to the same object
console.log( original === testMe ); // true
So when you return
return {
...state,
start: true,
}
you are creating and returning a new object, so it naturally can not reference the same object that you created and assigned to the variable name expectedState.
If what you are interested in is not strict equality, but rather just that the content in the two objects are the same, there exists other methods than .equal, usually named something with deep (since they go deep into the objects/arrays/whatever to check if the values are the same).
Chai.js has examples of both expect(x).to.equal(y) and expect(x).to.deep.equal(y) in their docs: http://chaijs.com/api/bdd/#method_equal
Your testing library probably has very similar, if not identical, syntax.