最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Check Store before API call NgRx Angular - Stack Overflow

programmeradmin1浏览0评论

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 badges
Add a ment  | 

2 Answers 2

Reset to default 5

Make a few conventions:

  1. state.Companies = null is initial state if no request to server has been sent yet
  2. state.Companies = [] is state after first request was sent but no panies returned from server
  3. use createSelector that filters your panies based on criteria you need
  4. use withLatestFrom in your effects which will enable you to check store state within effects

Now, turn the logic the other way around:

  1. when you look for panies, first fire an action that will trigger effects
  2. in that effect, check if state.Companies is null or not
  3. if its null > fire api request
  4. if its not null > fire an action that will trigger selector for filtering
  5. if data was not found even if state.Companies was not null that means either you need to refresh your Companies 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);
                }
              });
            }
          });
发布评论

评论列表(0)

  1. 暂无评论