Angular 2 Meteor Tutorial User Authentication Problems


#1

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’.


#2

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


#3

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());
  }
}

#4

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');
      }
    }
  }
}

#5

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


#6

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());
      }


}