johannesjo / angular2-promise-buttons

Chilled loading buttons for angular2
https://johannesjo.github.io/angular2-promise-buttons/#demo
MIT License
86 stars 28 forks source link

Can't bind to 'promiseBtn' since it isn't a known property of 'button'. #6

Closed ghost closed 7 years ago

ghost commented 7 years ago

Hello. I'm a newbie in Angular. What am I doing wrong?

My app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { UIRouterModule } from '@uirouter/angular';
import { ResourceModule } from 'ngx-resource';
import { Angular2PromiseButtonModule } from 'angular2-promise-buttons';

import { uiRouterConfig } from './app.config';
import { AppComponent } from './app.component';
import { AuthModule } from './Auth/auth.module';

@NgModule({
  imports: [
    BrowserModule,
    UIRouterModule.forRoot(uiRouterConfig),
    ResourceModule.forRoot(),
    Angular2PromiseButtonModule.forRoot(),

    AuthModule,
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule { }

in AuthModule I have a component where I do the following:

import { Component, OnInit } from '@angular/core';
import { UIRouter } from '@uirouter/angular';
import { DataService, SocialLoginResponse } from '../../services/index';

@Component({
  selector: 'social-login',
  templateUrl: './social-login.component.html',
  styleUrls: ['./social-login.component.scss'],
})
export class SocialLoginComponent implements OnInit {
  ajaxRequest: Promise<any>;

  constructor(
    private dataService: DataService,
    private router: UIRouter,
  ) {}

  ngOnInit(): void {}

  loginWith(social:('Facebook' | 'Google' | 'Github')): void {
    this.ajaxRequest = this.dataService[`loginWith${social}`]()
      .$observable.toPromise()
      .then(
        (response: SocialLoginResponse) => {
          if (response.authorization_url) {
            window.open(response.authorization_url, '_self');
          } else {
            this.router.stateService.go('dashboard.index');
          }
        },
      );
  }
}
<div>
  <button type="button" (click)="loginWith('Facebook')" [promiseBtn]="ajaxRequest">Facebook</button>
  <button type="button" (click)="loginWith('Google')">Google</button>
  <button type="button" (click)="loginWith('Github')">Github</button>
</div>

I get the following error when I open the page https://i.imgur.com/h09SYa0.png I use Angular 4.1.3.

johannesjo commented 7 years ago

Hey there! If you want to use a directive from inside another module, you also might need to import the promise button module there, too, e.g.:

@NgModule({
  imports: [
    Angular2PromiseButtonModule.forRoot(),
    // or maybe like this here, not sure:
    Angular2PromiseButtonModule,
  ],
})
export class AuthModule { }

I'm not sure, but it might be that you can skip out the forRoot part.

ghost commented 7 years ago

@johannesjo thanks, it helped. I imported the module in my child module and now it works. The .formRoot() part was mandatory by the way.

Is there any way to import this module only once in the global module? For example, I import ToasterModule only in my parent module and it works everywhere, including my child modules

johannesjo commented 7 years ago

@maxkorz that's interesting. I'll check out, how they do this. Maybe I'm missing something.

johannesjo commented 7 years ago

Weirdly I'm unable to find any difference from how the modules are declared: https://github.com/Stabzs/Angular2-Toaster/blob/master/src/toaster.module.ts https://github.com/johannesjo/angular2-promise-buttons/blob/master/src/angular2-promise-buttons.module.ts

And from all I've read at least with angular4 a directive should be available in other modules, too when imported like you did. I think that this might be related to the forRoot method. I'll try to dig into it a little further, but I'm glad for suggestions how to solve this while maintaining the possibility of a global config.

ghost commented 7 years ago

@johannesjo I will look into it. Something's wrong for sure. According to documentation I should not call .forRoot in child modules:

Call forRoot only in the root application module, AppModule. Calling it in any other module, particularly in a lazy-loaded module, is contrary to the intent and can produce a runtime error.

Remember to import the result; don't add it to any other NgModule list.

johannesjo commented 7 years ago

Thank you very much!

johannesjo commented 7 years ago

@maxkorz Does this work now for you?

ghost commented 7 years ago

@johannesjo Yes. I found a very useful article on angularjs scopes. Understanding Angular modules (NgModule) and their scopes.

where it says

components you declared are only usable in the current module

So I created a "shared" module and now I do all the declarations there and then I export everything. It works fine.

johannesjo commented 7 years ago

@maxkorz thanks for sharing! That's an interesting article!