Home > Software engineering >  TypeScript/Angular/Ngrx - Trying to access the state, getting back an array but can't access an
TypeScript/Angular/Ngrx - Trying to access the state, getting back an array but can't access an

Time:09-16

notes.reducer.ts:

import { Action, createReducer, on, } from "@ngrx/store";

import * as NotesActions from "./notes.actions"
import { Note } from "../note.model";


export interface NotesState {
  notes: Note[]
}

const initialState: NotesState = {
  notes: [new Note('title', 'body')]
}

const _notesReducer = createReducer(
  initialState,
  on(
    NotesActions.saveNewNote,
    (state, action) => ({
      ...state,
      notes: state.notes.concat(action.note)
    })
  )
)

export function notesReducer(state: NotesState, action: Action) {
  return _notesReducer(state, action)
}

note-list.component.ts:

import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs';
import { Note } from '../note.model';
import { NotesState } from '../store/notes.reducer';

@Component({
  selector: 'app-note-list',
  templateUrl: './note-list.component.html',
  styleUrls: ['./note-list.component.css']
})
export class NoteListComponent implements OnInit {

  notesArray!: Note[]
  notesSubscription: Subscription;

  constructor(private store: Store<NotesState>) { }

  ngOnInit(): void {
    this.notesSubscription = this.store.select('notes').subscribe((notes: Note[]) => {
      this.notesArray = notes;
      console.log(notes)
      console.log(notes[0])
    })
  }

  ngOnDestroy(): void {
    this.notesSubscription.unsubscribe()
  }

} 

note.model.ts:

export class Note {
  constructor(public title: string, public body: string) {}
}

app.module.ts:

import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools'
import { environment } from 'src/environments/environment';


import { AppComponent } from './app.component';
import { NoteDetailComponent } from './note-detail/note-detail.component';
import * as fromNotes from './store/notes.reducer';
import { NoteListComponent } from './note-list/note-list.component';
import { NoteTileComponent } from './note-list/note-tile/note-tile.component';

@NgModule({
  declarations: [
    AppComponent,
    NoteDetailComponent,
    NoteListComponent,
    NoteTileComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    StoreModule.forRoot({notes: fromNotes.notesReducer}),
    StoreDevtoolsModule.instrument({logOnly: environment.production}),

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

The output of the console.logs are:

{notes: Array(1)} notes: Array(1) 0: Note {title: 'title', body: 'body'} length: 1 [[Prototype]]: Array(0) [[Prototype]]: Object

and

undefined

What am I doing wrong here? The object I'm getting back obviously contains data, but I have no way of accessing it. If I try to iterate through notes, I get an error telling me that notes is not iterable. If I try to use an Array function such as notes.forEach, it tells me that it is not a valid function. I thought maybe it's returning the notes array wrapped inside an object, but notes.notes tells me that 'notes' does not exist on type 'Note[]', and notes.keys returns undefined.

screenshot of console output

CodePudding user response:

Your notes are a level deeper try, this.store.select('notes.notes')

CodePudding user response:

As @timdeschryver said the notes array is a level deeper. Try this (notice the type has been changed to any as its an Object here not an array

ngOnInit(): void {
 this.notesSubscription = this.store.select('notes').subscribe((notes: any) => {
  this.notesArray = notes.notes; //level deeper here!
  console.log(notes)
  console.log(notes[0])
})

}

  • Related