Angular 2 Meteor Tutorial User Authentication Problems

Hello, I am new to Meteor and most JS technologies as well. So I’m following this tutorial
http://www.angular-meteor.com/tutorials/socially/angular2/user-accounts-authentication-and-permissions

I’ve wrote the code as is needed, however now even as a logged in user I cannot get into the details page.

My Atom Typescript compiler and the terminal give me the following errors -

client/imports/parties/parties-form.component.ts (23, 22): Property ‘user’ does not exist on type ‘PartiesFormComponent’.
client/imports/parties/party-details.component.ts (19, 40): Property ‘partyId’ does not exist on type ‘PartyDetails’.

So does your PartyDetails class have a field ‘partyId’ defined, outside of the constructor or member functions?

I should look something like this:

class PartyDetails implements OnInit {
    partyId: string;

    ngOnInit() {
      this.partyId = //do something
    }

}

same goes for the PartiesFormComponent

Here are my codes

import {Component, NgZone, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES} from '@angular/router';
import {Router,ActivatedRoute} from '@angular/router';
import {Tracker} from 'meteor/tracker'

import {Parties} from '../../../both/collections/parties.collection';
import {Party} from '../../../both/interfaces/party.interface';
import {CanActivate} from '@angular/router';

import template from './party-details.component.html';

@Component({
  selector: 'party-details',
  template,
  directives: [ROUTER_DIRECTIVES]
})


export class PartyDetailsComponent implements OnInit {
  partyId: string;
  party: Party;

  constructor(private route: ActivatedRoute, private ngZone: NgZone,private router: Router) {}

  ngOnInit(){
    this.route.params
    .map(params=> params['partyId'])
    .subscribe(partyId=> {
      this.partyId = partyId

      Tracker.autorun(()=>{
        this.ngZone.run(()=>{
          this.party = Parties.findOne(this.partyId);
        });
      });
    });
  }

  goBack(){
    this.router.navigate(['/']);
  }
  saveParty(){
    if (this.party && this.party.owner == Meteor.userId() || !this.party.owner) {
      Parties.update(this.party._id,{
        $set: {
          name: this.party.name,
          description: this.party.description,
          location: this.party.location
        }
      });
      this.goBack();
    }//saveParty
    else {
      alert('You cannot change this party!')
    }
    }


}

export class PartyDetails implements CanActivate {
  partyId: string;
  // party: Party;
  canActivate() {

    const party = Parties.findOne(this.partyId);
    console.log('party:' +party);
    console.log('owner:' +party.owner);

    return (party && party.owner == Meteor.userId());
  }
}

And

import { Component, OnInit } from '@angular/core';
import { REACTIVE_FORM_DIRECTIVES, FormGroup, FormBuilder, Validators } from '@angular/forms';
import {Meteor} from 'meteor/meteor';

import { Parties } from '../../../both/collections/parties.collection';

import {MeteorComponent} from 'angular2-meteor';
import {InjectUser} from 'angular2-meteor-accounts-ui';

import template from './parties-form.component.html';

@Component({
  selector: 'parties-form',
  template,
  directives: [REACTIVE_FORM_DIRECTIVES]
})
@InjectUser('user')
export class PartiesFormComponent extends MeteorComponent implements OnInit {
  addForm: FormGroup;
  user: Meteor.User;
  constructor(private formBuilder: FormBuilder) {
    super();
    console.log(this.user);
  }

  ngOnInit() {
    this.addForm = this.formBuilder.group({
      name: ['', Validators.required],
      description: [],
      location: ['', Validators.required]
    });
  }

  resetForm() {
    this.addForm.controls['name']['updateValue']('');
    this.addForm.controls['description']['updateValue']('');
    this.addForm.controls['location']['updateValue']('');
  }

  addParty() {
    if (this.addForm.valid) {
      if (Meteor.userId()) {
        Parties.insert(Object.assign({},this.addForm.value, {owner: Meteor.userId() }));

        // XXX will be replaced by this.addForm.reset() in RC5+
        this.resetForm();
      }
      else {
        alert('Please log in to add a party');
      }
    }
  }
}

Hmm it doesn’t make sense to have both PartyDetailsComponent and PartyDetails classes.

I guess you copied this from the tutorial:

import { CanActivate } from '@angular/router';

import template from './party-details.component.html';

@Component({
  selector: 'party-details',
  template,
  directives: [ROUTER_DIRECTIVES]
})
export class PartyDetails implements CanActivate {
  ...

  canActivate() {
    const party = Parties.findOne(this.partyId);
    return (party && party.owner == Meteor.userId());
  }
}

But it looks like they actually mean PartyDetailsComponent instead of PartyDetails as it has a Component decorator with ./party-details.component.html as template.

So i guess you could try to add the code from PartyDetails to PartyDetailsComponent

well the app build process is clear this way… how ever it is not doing what it’s supposed to do
I am still able to access partydetails as a non owner.

This is how I changed the code
export class PartyDetailsComponent implements OnInit,CanActivate {
partyId: string;
party: Party;

  constructor(private route: ActivatedRoute, private ngZone: NgZone,private router: Router) {}

  ngOnInit(){
    this.route.params
    .map(params=> params['partyId'])
    .subscribe(partyId=> {
      this.partyId = partyId

      Tracker.autorun(()=>{
        this.ngZone.run(()=>{
          this.party = Parties.findOne(this.partyId);
        });
      });
    });
  }

  goBack(){
    this.router.navigate(['/']);
  }
  saveParty(){
      if (this.party && this.party.owner == Meteor.userId() || !this.party.owner) {
        Parties.update(this.party._id,{
          $set: {
            name: this.party.name,
            description: this.party.description,
            location: this.party.location
          }
        });
        this.goBack();
      }//saveParty
        else {
          alert('You cannot change this party!')
        }
    }

      canActivate() {

        const party = Parties.findOne(this.partyId);
        console.log('party:' +party);
        console.log('owner:' +party.owner);

        return (party && party.owner == Meteor.userId());
      }


}