Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No provider for Http! #28

Closed
louisscruz opened this issue Jan 24, 2016 · 7 comments
Closed

No provider for Http! #28

louisscruz opened this issue Jan 24, 2016 · 7 comments

Comments

@louisscruz
Copy link

I am getting the following error:

EXCEPTION: No provider for Http! (Login -> AuthHttp -> Http)

main.ts

import {provide} from 'angular2/core';
import {bootstrap, ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/browser';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {HTTP_PROVIDERS, ConnectionBackend} from 'angular2/http';
import {App} from './app/app';
import {AuthHttp, JwtHelper, AuthConfig} from 'angular2-jwt';
import {AuthService} from './app/services/auth/authService';

document.addEventListener('DOMContentLoaded', function main() {
  bootstrap(App, [
    ('production' === process.env.ENV ? [] : ELEMENT_PROBE_PROVIDERS),
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(LocationStrategy, { useClass: HashLocationStrategy }),
    provide(AuthConfig, { useFactory: () => {
      return new AuthConfig({
        headerName: 'Authorization',
        headerPrefix: 'Bearer ',
        tokenName: 'auth_token',
        noJwtError: true
      });
    }}),
    AuthHttp,
    AuthService,
    ConnectionBackend
  ])
  .catch(err => console.error(err));
});

login.ts

import {Component} from 'angular2/core';
import {
  FORM_DIRECTIVES,
  FormBuilder,
  ControlGroup,
  Validators,
  AbstractControl,
  Control
} from 'angular2/common';
import {Http, Headers} from 'angular2/http';
import {Router} from 'angular2/router';
import {ButtonRadio} from 'ng2-bootstrap/ng2-bootstrap';
import {AuthHttp, JwtHelper, AuthConfig} from 'angular2-jwt';
import {AuthService} from '../../services/auth/authService';
import {AlertService} from '../../services/alerts/alertsService';
import {User} from '../../datatypes/user/user';

@Component({
  selector: 'login',
  template: require('./login.html'),
  directives: [ ButtonRadio, FORM_DIRECTIVES ],
  providers: [Http, AuthService, AlertService]
})

export class Login {
  loginForm: ControlGroup;
  email: AbstractControl;
  password: AbstractControl;
  constructor(
    private http: Http,
    private authHttp: AuthHttp,
    private authService: AuthService,
    private alertService: AlertService,
    private fb: FormBuilder,
    private router: Router) {
      function emailValidator(control: Control): { [s: string]: boolean } {
        if (control.value.length > 0 && !control.value.match(/.+@.+\..+/i)) {
          return {invalidEmail: true};
        }
      }
      function passwordLengthValidator(control: Control): { [s: string]: boolean } {
        if (control.value !== '' && control.value.length < 6) {
          return {passwordLengthInvalid: true};
        }
      }
      this.loginForm = fb.group({
        'email': ['', Validators.compose([
          Validators.required, emailValidator])],
        'password': ['', Validators.compose([
          Validators.required, passwordLengthValidator])]
      });
      this.email = this.loginForm.controls['email'];
      this.password = this.loginForm.controls['password'];

      this.authService = authService;
      this.alertService = alertService;
  }
  login(user) {
    console.log('inside login.ts function');
    console.log(user);
    this.authService.login(user)
    .subscribe(
      res => {
        this.authService.saveJwt(res.auth_token);
      },
      err => {
        (<Control>this.loginForm.controls['password']).updateValue('');
        (<Control>this.loginForm.controls['password']).pristine = true;
        this.alertService.addAlert('There was an error loggin in.', 'danger');
      },
      () => {
        this.authService.token = localStorage.getItem('auth_token');
        this.router.navigate(['Home']);
      }
    );
  }
}

authService.ts

import {Http, Headers} from 'angular2/http';
import {Router} from 'angular2/router';
import {Injectable} from 'angular2/core';
import {AuthHttp, JwtHelper, AuthConfig} from 'angular2-jwt';

import {User} from '../../datatypes/user/user';

@Injectable()
export class AuthService {
  token: any;
  jwtHelper: JwtHelper = new JwtHelper();
  constructor(private http: Http, private router: Router, private authHttp: AuthHttp) { }
  saveJwt(jwt) {
    if (jwt) {
      localStorage.setItem('auth_token', jwt);
      this.token = localStorage.getItem('auth_token');
    }
  };
  deleteJwt() {
    localStorage.removeItem('auth_token');
    this.token = localStorage.getItem('auth_token');
  };
  isAuth() {
    var decoded: any;
    //decoded = this.jwtHelper(this.token);
    var date = new Date(0);
    date.setUTCSeconds(decoded.exp);
    if (date === null) {
      return false;
    }
    console.log(date);
    return (date.valueOf() > (new Date().valueOf()));
  }
  login(user) {
    console.log('inside authService.login');
    var header = new Headers();
    header.append('Content-Type', 'application/json');

    return this.authHttp.post('http://localhost:3000/login', JSON.stringify(user), {
      headers: header
    })
    .map(res => res.json());
    /*.subscribe(
      data => {
        alert('logging in');
        this.saveJwt(data.auth_token);
      },
      err => console.log(err),
      () => this.router.navigate(['Home'])
    );*/
  }
  logout() {
    /*var jwt = localStorage.getItem('auth_token');
    var authHeader = new Headers();
    if (jwt) {
      authHeader.append('Authorization', jwt);
    }*/
    var token = localStorage.getItem('auth_token');
    var header = new Headers();
    header.append('Content-Type', 'application/json');
    header.append('Authorization', token);
    console.log(token);

    return this.authHttp.delete('http://localhost:3000/logout', {
      headers: header
    })
    .map(res => res.json());
    /*.subscribe(
      data => this.deleteJwt(),
      err => console.log(err),
      () => this.router.navigate(['Login'])
    );*/
  }
  isLoggedIn() {
    //_jwt === localStorage.getItem('auth_token');
  }
}
@chenkie
Copy link
Contributor

chenkie commented Jan 24, 2016

Can you try passing Http to the deps array?

...

import {Http} from 'angular2/http';

...

provide(AuthHttp, {
  useFactory: (http) => {
    return new AuthHttp(new AuthConfig(), http);
  },
  deps: [Http]
})

...

Let me know if that works :)

@louisscruz
Copy link
Author

That does it!!! Thank you! Never would have thought of doing that.

It's been a month or so since I've started with Angular2-jws. Is there any mention of this approach in the docs?

@chenkie
Copy link
Contributor

chenkie commented Jan 25, 2016

This is from a recent change. I'll update the readme to reflect it. Thanks!

@escardin
Copy link
Contributor

You should just be able to provide auth config and authhttp like this:

provide(AuthConfig, {useValue: new AuthConfig()}),AuthHttp

I believe when I pulled the injector out of the AuthHttp constructor I updated the example (though I used a factory and not a value).

@chenkie chenkie closed this as completed Feb 9, 2016
@rvetere
Copy link

rvetere commented Mar 8, 2016

provide(AuthConfig, {useValue: new AuthConfig()}),AuthHttp

This is still not working on my side, beta.8 - i still get an exception:

Cannot resolve all parameters for 'AuthConfig'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'AuthConfig' is decorated with Injectable.

Error: Cannot read property 'getOptional' of undefined

Even if i try to give him the local config param in my provide, the error won't go away. Are now actually Decorators missing in the current AuthConfig implementation?

Update:

I've just copied over the variant to bootstrap from the project page (angular2-jwt):

provide(AuthHttp, { useFactory: (http) => { return new AuthHttp(new AuthConfig({ headerName: 'YOUR_HEADER_NAME', headerPrefix: 'YOUR_HEADER_PREFIX', tokenName: 'YOUR_TOKEN_NAME', tokenGetter: 'YOUR_TOKEN_GETTER_FUNCTION', noJwtError: true }), http); }, deps: [Http] })

Now this variant is working, yay! :) I know, my strings i'm defining for all the values in my config object are total non-sense, i just wanted to make it running first.. but leaving them empty has taken me into another error again (can't remember which one right now)

@escardin
Copy link
Contributor

escardin commented Mar 8, 2016

It doesn't need to be decorated if you use it via useValue, because you are instantiating it directly.

Can you provide us with your entire bootstrap? Are you providing AuthConfig anywhere else?

You can look at this plunk as well for ideas: http://plnkr.co/edit/pKazgpkXLX9ZgV02YuVf?p=preview

@rvetere
Copy link

rvetere commented Mar 8, 2016

Thx @escardin for your answer - we crossed each other, i've just made an update on my comment how i could fix it ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants