I am creating NgRx application but I am quite confused about its implementation as it is my first app with NgRx. I have a store with "Companies" state. I gotta search the panies and return if found. If the required pany is not found it should call the API and fetch the results likewise but the process is circular and runs infinite time.
Here is my code:
thispanySearchCtrl.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged()
)
.subscribe(val => {
if (val !== ' ' || val !== '') {
this.store.select(getCompanys).subscribe(data => {
console.log(data);
//filter panies on the basis of search text
const filteredData = data.filter(x =>
x['name']
.toLowerCase()
.startsWith(thispanySearchCtrl.value.toLowerCase())
);
console.log(filteredData);
if (filteredData.length === 0) { //if data is not found in store
console.log('got a call');
this.store.dispatch(
new CompanyActions.find({
where: { name: { regexp: `${val}/i` } } // call to API to search with regExp
})
);
} else {
// if required data found in store
console.log('got no call');
this.filteredCompanies$ = of(filteredData);
}
});
}
});
This process runs fine if data is found in store. If data is not found in store or I dont get any results from API call it runs infinitely. How can I make this correct?
I am creating NgRx application but I am quite confused about its implementation as it is my first app with NgRx. I have a store with "Companies" state. I gotta search the panies and return if found. If the required pany is not found it should call the API and fetch the results likewise but the process is circular and runs infinite time.
Here is my code:
this.panySearchCtrl.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged()
)
.subscribe(val => {
if (val !== ' ' || val !== '') {
this.store.select(getCompanys).subscribe(data => {
console.log(data);
//filter panies on the basis of search text
const filteredData = data.filter(x =>
x['name']
.toLowerCase()
.startsWith(this.panySearchCtrl.value.toLowerCase())
);
console.log(filteredData);
if (filteredData.length === 0) { //if data is not found in store
console.log('got a call');
this.store.dispatch(
new CompanyActions.find({
where: { name: { regexp: `${val}/i` } } // call to API to search with regExp
})
);
} else {
// if required data found in store
console.log('got no call');
this.filteredCompanies$ = of(filteredData);
}
});
}
});
This process runs fine if data is found in store. If data is not found in store or I dont get any results from API call it runs infinitely. How can I make this correct?
Share Improve this question asked Aug 17, 2018 at 12:57 Shahrukh ShahidShahrukh Shahid 4186 silver badges18 bronze badges2 Answers
Reset to default 5Make a few conventions:
state.Companies = null
is initial state if no request to server has been sent yetstate.Companies = []
is state after first request was sent but no panies returned from server- use
createSelector
that filters your panies based on criteria you need - use
withLatestFrom
in your effects which will enable you to check store state within effects
Now, turn the logic the other way around:
- when you look for panies, first fire an action that will trigger effects
- in that effect, check if
state.Companies
isnull
or not - if its
null
> fire api request - if its not null > fire an action that will trigger selector for filtering
- if data was not found even if
state.Companies
was notnull
that means either you need to refresh yourCompanies
collection or the value doesn't exist on server
Create another action named dataNotFound
. If you found data then set its state isFound
to true and if data does not find, set its state isFound
to false and always before sending call with regex check isFound
that either data was found in previous call or not. If data was not found then don't send call again.
I've made a little bit change in your code to manage this. You just have to create an action dataNotFound
now.
this.panySearchCtrl.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged()
)
.subscribe(val => {
if (val !== ' ' || val !== '') {
this.store.select(getCompanys).subscribe(data => {
console.log(data);
//filter panies on the basis of search text
const filteredData = data.filter(x =>
x['name']
.toLowerCase()
.startsWith(this.panySearchCtrl.value.toLowerCase())
);
console.log(filteredData);
if (filteredData.length === 0) { //if data is not found in store
console.log('got a call');
this.store.select(isDataFound).subscribe(isFound => {
if(isFound) {
this.store.dispatch(
new CompanyActions.find({
where: { name: { regexp: `${val}/i` } } // call to API to
search with regExp
})
);
} else {
this.store.dispatch(new CompanyActions.dataNotFound({isFound: false}));
}
});
} else {
// if required data found in store
console.log('got no call');
this.store.dispatch(new CompanyActions.dataNotFound({isFound: true}));
this.filteredCompanies$ = of(filteredData);
}
});
}
});