The ability to reply to discussions is limited to PRO members. Want to join in the discussion? Click here to subscribe now.

Updating Data with Scan

Updating Data with Scan

2:10
You often need to update the data flowing through the stream with custom logic based on what you need to output. This lesson covers how to use `scan` for collecting and updating the outputs as your stream progresses.
Watch this lesson now
Avatar
egghead.io

You often need to update the data flowing through the stream with custom logic based on what you need to output. This lesson covers how to use scan for collecting and updating the outputs as your stream progresses.

Avatar
Leesh

Would be worth mentioning you are using Rx.Js 5 Beta! It's not very clear and I spent a good while trying to figure out why switchMapTo wasn't working.

Avatar
Albert

So essentially scan is equal to reduce, right? I don't understand why they always try to make another name in the world of RFP.

Avatar
John

@Albert - no, reduce can only occur once a stream has completed. scan continues to gather output from streams over time and can continually update.

They to have the same api/usage, but the distinction is critical.

In reply to Albert
Avatar
Ahmed

@john_lindquist you've made it abundantly clear that we shouldn't include business logic instead of a .subscribe() method.

So I'm creating a canActivate guard to protect against users going to an invalid route, and I can't help but build logic into the subscribe method. Is there a better way to do this?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { Subject } from 'rxjs/Subject';

import { Apollo, ApolloQueryObservable } from 'apollo-angular';

import { GQTicketId } from './ticket.model';



@Injectable()
export class TicketRouteActivatorService implements CanActivate {

  public ticket;
  private returnTrue: Subject<Boolean> = new Subject<Boolean>();
  private ticketSubscription: Subscription;

  constructor(private apollo: Apollo, 
              private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot ) {

    this.ticketSubscription = this.apollo.watchQuery({
      query: GQTicketId,
      variables: {
        _id: +route.params['id']
      }
    }).subscribe(({data})=>{
      this.ticket = data['ticket'];

      // this doesn't seem right, atleast based on the guidance from John Linquidst. Should this logic be "Rx'd" some how?
      if(!this.ticket) {
          this.router.navigate(['provision/requests/error/404']);
      } else {
        this.returnTrue.next(true);
      }

    }
    );

      if (this.returnTrue) return true;
  }

  // do we need to unsubscribe?
  ngOnDestroy():void {
      this.ticketSubscription.unsubscribe();
  }

}

<!-- end snippet -->

Avatar
Oleksii

Wouldn't it be a bit simpler if we used the counter value instead of object?

.scan((acc) => ++acc, -1)

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?