by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 26 05:47
    amithegde commented #20
  • Jul 26 05:46
    amithegde commented #20
  • Jul 06 09:12
    the0rem commented #20
  • Oct 15 2019 16:45
    johannesjo commented #20
  • Sep 21 2019 04:04
    JimTheMan closed #16
  • May 04 2019 00:15
    felixunivers edited #17
  • Apr 29 2019 21:30
    felixunivers opened #17
  • Apr 10 2019 21:15
    rezord opened #16
  • Jan 31 2019 20:44
    alex-okrushko commented #1511
  • Jan 31 2019 20:21
    brandonroberts edited #1538
  • Jan 31 2019 20:20
    brandonroberts edited #1538
  • Jan 31 2019 20:18
    brandonroberts labeled #1538
  • Jan 31 2019 20:18
    brandonroberts labeled #1538
  • Jan 31 2019 20:18
    brandonroberts opened #1538
  • Jan 31 2019 12:11
    timdeschryver closed #1536
  • Jan 31 2019 12:11
    timdeschryver commented #1536
  • Jan 31 2019 12:08
    timdeschryver closed #1537
  • Jan 31 2019 12:08
    timdeschryver commented #1537
  • Jan 31 2019 11:59
    olefrank commented #1036
  • Jan 31 2019 11:59
    olefrank commented #1036
Ohm0n
@thecyberd3m0n_gitlab
it's not a atomic unit test, I want to test behaviour of whole library
my mistake was I treat it('should do something', () => {...}) as single test
so now test looks like this:

import { MasterSessionService } from './../lib/services/masterSession.service';
import { TestBed, async } from '@angular/core/testing';
import 'firebase/database';
import { SecureChatDispatchers } from '../lib/services/secure-chat.dispatchers';
import { SecureChatSelectors } from '../lib/services/secure-chat.selectors';
import { SecureChatMode } from '../lib/store/reducers/secure-chat.reducer';
import { activeSessionsAdapter } from './../lib/adapters/activeSessions.adapter';
import { messagesStateAdapter } from './../lib/adapters/decryptedMessages.adapter';
import { secureChatSessionsAdapter } from './../lib/adapters/secureChatSession.adapter';
import { configureTestingModule } from './configureTestBed';
import { PendingSession } from '../lib/models/pendingSession.model';
import { ActiveSession } from '../lib/models/activeSession.model';

fdescribe('Test secure-chat', () => {
  let dispatchers: SecureChatDispatchers;
  let selectors: SecureChatSelectors;
  let masterSessionService: MasterSessionService;
  let sessionId: string;
  beforeEach(
    configureTestingModule
  );
  beforeEach(() => {
    dispatchers = TestBed.inject<SecureChatDispatchers>(SecureChatDispatchers);
    selectors = TestBed.inject<SecureChatSelectors>(SecureChatSelectors);
    masterSessionService = TestBed.inject<MasterSessionService>(MasterSessionService);
  });

  it('should be able to create session', async (done) => {
    // let's create session
    dispatchers.init();

    const mainSub = selectors.mode$.subscribe((mode) => {
      if (mode === SecureChatMode.EMPTY) {
        dispatchers.setupProfile({
          name: 'test'
        });
      } else if (mode === SecureChatMode.READY) {
        dispatchers.startSession();
        const pendingSessionsSub1 = selectors.pendingSessions$.subscribe((pendingSessions: PendingSession[]) => {
          if (pendingSessions.length > 0) {
            expect(pendingSessions[0].id).toBeTruthy();
            sessionId = pendingSessions[0].id;
            mainSub.unsubscribe();
            pendingSessionsSub1.unsubscribe();
            done();
          }
        });
      }
    });
  });

  it('should be able to join to remembered session', async (done) => {
    dispatchers.init();
    selectors.mode$.subscribe((mode) => {
      if (mode === SecureChatMode.EMPTY) {
        selectors.activeSessions$.subscribe((activeSessions: ActiveSession[]) => {
          if (activeSessions.length > 0) {
            expect(activeSessions[0].id).toBeTruthy();
            done();
          }
        });
        dispatchers.joinSession({
          sessionId
        });
      }
    });
  });

});
first 'it' creates the session and stores id by first client. Second 'it' joins that session. beforeEach has callback 'configureTestingModule' - it means Angular will restart itself between 'it's'. So that's kind of whole workflow test (now it passes)
RoboZoom
@RoboZoom
Aren't the 'it' statements run in parallel? Are you counting on the first 'it' to be run before the second 'it'?
@thecyberd3m0n_gitlab
Ohm0n
@thecyberd3m0n_gitlab
if yes, I should disable this behaviour
but I see test are passed now
Ohm0n
@thecyberd3m0n_gitlab
no it doesn't run by parallel by default, you need to add 'parallel' into config (https://stackoverflow.com/questions/42965037/is-it-possible-to-run-parallel-tests-using-karma) but it is not desired behaviour in this case. My CI has some time and it doesn't need to be ultra fast.
RoboZoom
@RoboZoom
ah, cool
RoboZoom
@RoboZoom
I'm trying to write my first effect, but the compiler is telling me that my object exiting the ofType function is of type never
addPerson$ = createEffect(() =>
      this.actions$.pipe(
          ofType(AdminActions.AdminAction.addPerson),
          tap((x) => "Add Person Effect Called!"),
Here, x in final line is typed as (parameter) x: never
Am I doing something wrong?
RoboZoom
@RoboZoom
The follow on is that in later code, I want to access a prop

Which I'm doing like this:

 concatMap((action) =>
          this.dataService
            .addNewPerson(action.myPerson)

But the compiler is providing an error when I try to access the prop

I can cast the action as a type, but I don't think I'm creating a type - I'm just defining the action via the NgRx createAction factory function
RoboZoom
@RoboZoom
ok - to answer my own question, if I pass the action itself, and not the string, then the type inference works to understand properties
RoboZoom
@RoboZoom
If I have a member property of an NgRx entity that is an array of literals (either string literals, or numbers), will that cause reference issues?
I want to have a way to list Id's for other objects I'm storing, like addresses
dev-ster
@dev-ster
How do you manage updates of many to many relations in ngrx?
HMAIDI Thamer
@hmaidithamer
Hello All,
Can lazy loaded features communicate state between features with ngrx in Angular 9?
dev-ster
@dev-ster
@hmaidithamer Sure, you can do that
HMAIDI Thamer
@hmaidithamer
@dev-ster i have two module person and card and i use lazy loading when i try to access to the card state i have an error that card state undefined because still not loaded
i need to access to the card state from person module
dev-ster
@dev-ster
@hmaidithamer If you need the state of the lazy loaded module that isn’t loaded yet you have to restructure your imports
You need to import the store you need before you can access it
HMAIDI Thamer
@hmaidithamer
image.png
@dev-ster
yes that's what i do exactly
@dev-ster
i import the needed feature inside my module
dev-ster
@dev-ster
Try to use combinereducers
You shouldn’t invoke the store module multiple times inside on module
dev-ster
@dev-ster
screenshot 2020-06-28 um 14.40.21.png
I’m trying to find out why the bundle size is too big
Do you spot anything suspicious?
I’m at an early stage with a few routes. Lazy loading won’t be an issue
I’m using Angular Material
cuznerdexter
@cuznerdexter

I have used Ngrx in the past and had no issues. Now I am trying to use Entities for 1st time and it is not working at all.

I have an Angular9+ app in an NX workspace calling some mock data from a service.

Anyone tell me what is wrong? I cannot figure it out.
(this is long post)

Actions file:

....
export const loadSheetData = createAction('[SheetData] Load SheetData');

export const loadSheetDataSuccess = createAction(
  '[SheetData] Load SheetData Success',
  props<{ sheetData: SheetDataEntity[] }>()
);
....

Effects file

....
@Injectable()
export class SheetDataEffects {
  loadSheetData$ = createEffect(() =>
    this.actions$.pipe(
      ofType(SheetDataActions.loadSheetData),
      fetch({
        run: (action) => {
          return this.bottomSheetSvc.getSheetData().pipe(
            tap((obj) => 
            catchError(error => of(new Error('Effect failed') ) ),
            map((data) => SheetDataActions.loadSheetDataSuccess({ sheetData: data}) ) );

        onError: (action, error) => {
          return SheetDataActions.loadSheetDataFailure({ error });
        },
      })
    )
  );
....

Model file

export interface SheetDataEntity {
  id: string | number; // Primary ID
  info: string;
  link: string;
  icon?: string; 
  isDisabled?: boolean;
}

Reducer file

export const SHEETDATA_FEATURE_KEY = 'sheetData';

export interface State extends EntityState<SheetDataEntity> {
  selectedId?: string | number; // which SheetData record has been selected
  loaded: boolean; // has the SheetData list been loaded
  error?: string | null; // last none error (if any)
}

export interface SheetDataPartialState {
  readonly [SHEETDATA_FEATURE_KEY]: State;
}

export const sheetDataAdapter: EntityAdapter<SheetDataEntity> = createEntityAdapter<
  SheetDataEntity
>();

export const initialState: State = sheetDataAdapter.getInitialState({
  // set initial required properties
  entities: {
    0: {}
  },
  loaded: false,
});

const sheetDataReducer = createReducer(
  initialState,
  on(SheetDataActions.loadSheetData, (state) => ({
    ...state,
    loaded: false,
    error: null,
  })),
  on(SheetDataActions.loadSheetDataSuccess, (state, { sheetData }) => 
  {
    console.log('TEMP1:', state, sheetData);
    let temp = sheetDataAdapter.setAll(sheetData, { ...state, loaded: true })
    console.log('TEMP2:', temp);
    return temp;
  }

  ),
  on(SheetDataActions.loadSheetDataFailure, (state, { error }) => ({
    ...state,
    error,
  }))
);

export function reducer(state: State | undefined, action: Action) {
  console.log('SHEET REDUCER::', state, action);
  return sheetDataReducer(state, action);
}

Selectors file

....
export const getAllSheetData = createSelector(
  getSheetDataState,
  (state: State) => selectAll(state)
);
....

Component file

sheetData$: Observable<SheetDataEntity[]>;

constructor(
    private store: Store<State>,
    ) {

      this.sheetData$ = this.store.pipe( select( selectors.getAllSheetData ) );
    }

  ngOnInit(): void {
    this.store.dispatch( actions.loadSheetData() );
  }

Template file

<sheet-item 
        *ngFor="let item of (sheetData$ | async)" 
        [item]="item" 
        (onUpdateSelectedLink)="updateSelectedLink($emit)">
    </sheet-item>
Dummy Data used:
dummyData: any = {
    ids: [5, 4, 3, 2, 1],
    entities: {
      1: {
        id: 1,
        info: 'test info 1',
        link: '/test1',
        icon: 'test icon 1', 
        isDisabled: false
      },
      2: {
        id: 2,
        info: 'test info 2',
        link: '/test2',
        icon: 'test icon 2', 
        isDisabled: false
      },
      3: {
        id: 3,
        info: 'test info 3',
        link: '/test3',
        icon: 'test icon 3', 
        isDisabled: false
      },
      4: {
        id: 4,
        info: 'test info 4',
        link: '/test4',
        icon: 'test icon 4', 
        isDisabled: false
      },
      5: {
        id: 5,
        info: 'test info 5',
        link: '/test5',
        icon: 'test icon 5', 
        isDisabled: false
      }
    }


  };
RoboZoom
@RoboZoom
What is it not doing correctly? What does "not working at all" mean?
Derek
@derekkite
@cuznerdexter not working at all means what?
:)
what is fetch in the effect?
how are you initializing the store in the module?
RoboZoom
@RoboZoom
I think the InitialState for the entity isn't being declared correctly
@derekkite knows 1000x more than me, but I don't think you can declare an entity substructure within the function for the entity adapter getInitialState function... that function produces an empty list of entities
RoboZoom
@RoboZoom
If you're assigning an entity, but not putting the ID in the ID array, that may be a problem
@cuznerdexter Said more clearly - the initial state you provide creates a mismatch within the entity structure because you created an item in the entity list, which is not compliant with the interface you provided SheetDataEntity without the matched key in the ID array. Is there a reason why you can't just have an empty entity list on initialization?
Derek
@derekkite
export const initialState: State = sheetDataAdapter.getInitialState({
  // set initial required properties
   loaded: false,
});
is adequate. iirc the entity object is initialized when the entity is created