Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
307 views
in Technique[技术] by (71.8m points)

angular - How to retrieve data (like an array of file list) using NGRX when component is loaded

I have a scenario where I want to display some array (eg: list of files)when component is loaded using NGRX.

So what I have done is created two actions as below

  1. GET_FILES => GetFiles as class

  2. SET_FILES => SetFiles as class

and an reducer maintaining the state like

export interface State {
  files: Files[];
}

const initialState: State = {
  files: []
};
 
export function filesReducer(
  state: State = initialState,
  action: FilesAction.FilesAction
) {
  switch (action.type) {
    case FilesAction.GET_FILES:
      return {
        ...state
      };
    case FilesAction.SET_FILES:
      const files: Files[] = action.payload;
      return {
        ...state,
        ...files
      };
    default:
      return state;
  }
}

Then there will be an effect that gets makes an rest api call to get the list of files and then effect will dispatch SET_FILES action.

@Effect()
getFiles = this.action$.pipe(
ofType(FilesAction.GET_FILES),
switchMap(() => {
  return this.http.get<Files[]>(environment.baseURI + 'api/get-files');
}),
map(filesState => {
  return new FilesAction.SetFiles(filesState);
})
);

And when component is loaded on ngOnInit we can dispatch an action of SET_FILES which inturn executes an effect which is then responsible to dispatch another action of SET_FILES.

export class FileListComponent implements OnInit {
  iFileId: number = 0;
  fileList: Files[] = [];
  constructor(private store: Store<fromApp.AppState>) {
 
    //Problem Area
    this.store.select('files').subscribe(files => {
      this.fileList = files.files;
      console.log('FileList:');
      console.log(this.fileList);
    });
  }
 
  ngOnInit(): void {
    this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
  }
}

Here, the problem is i am successfully able to dispatch action on ngOnInit and if i console.log then i will get list of files but how do i store that in a variable like i am trying to do in constructor ?

question from:https://stackoverflow.com/questions/65831211/how-to-retrieve-data-like-an-array-of-file-list-using-ngrx-when-component-is-l

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In your component ts store a reference to the selector result in an observable:

export class FileListComponent implements OnInit {
  iFileId: number = 0;
  fileList$ = this.store.select('files');  // <<<-- add this

  constructor(private store: Store<fromApp.AppState>) {}
 
  ngOnInit(): void {
    this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
  }
}

In your template:

 <p *ngIf="fileList$ | async as fileList" *ngFor="let file of fileList.files">
   {{ file }}
 </p>

Note the ngIf.. as syntax to subscribe and check the emitted value is truthy - you can then safely use fileList in the ngFor.

Other recommendations

  1. You do not need the FilesAction.GET_FILES case in your reducer, as it does not alter the state.

  2. Name your reducers after the related events that triggered them (see https://2018.ng-conf.org/sessions/good-action-hygiene-ngrx/ 4:30):

   GET_FILES => FILES_REQUESTED  
   SET_FILES => FILES_LOADED

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...