5

I am trying to use jquery to my Angular 4 app.I had followed all the steps to install jquery on my Angular 4.However jquery still dont work. I had put the jquery code on the component like this.

home.component.ts

import * as jQuery from 'jquery'
import { Component, OnInit } from '@angular/core';


 @Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

constructor(db: AngularFireDatabase,public authService: AuthService,public 
afAuth: AngularFireAuth,) { 
$(document).ready(function(){
  $("#showAppinfo").click(function(){
      $("#appinfo").slideToggle();
  });
});
ngOnInit()
{}
}

And my Html is the following home.component.html

    <h1>This is Home page!!</h1>
    <h2 id="showAppinfo">Basic App-info</h2>
    <ul class="list-group" id="appinfo">
      <li class="list-group-item">Publiser: {{ (appinfo | async)?.Publisher }}</li>
      <li class="list-group-item">Publication_Year: {{ (appinfo | async)?.Publication_Year }}</li>
      <li class="list-group-item">Version: {{ (appinfo | async)?.Version }}</li>
      <li class="list-group-item">Registered Users: {{ (appinfo | async)?.Rusers }}</li>
      <li class="list-group-item">Languages: {{ (appinfo | async)?.Language }}(Only)</li>
   </ul>

But nothing happens when I click on <h2 id="showAppinfo">Basic App-info</h2>. Can you tell my if I am using the jquery code in the correct place?? The problem is on code or on the jquery instalation??

Vasilis Michail
  • 403
  • 2
  • 6
  • 17

6 Answers6

2

The basic problem is that you're trying to manipulate your template in the constructor. But when your component constructor executes, #showAppinfo and #appInfo elements don't exist yet because the view has not been built.

Operations that depend on view elements need to be performed at the earliest in the ngAfterViewInit lifecycle hook

export class HomeComponent implements OnInit, OnAfterViewInit 
...

ngAfterViewInit(){
  // do your template manipulation here
}

You can test this with something like console.log($("#showAppinfo")) and you'll see that it doesn't log any element constructor(), but it does in ngAfterViewInit()

BeetleJuice
  • 39,516
  • 19
  • 105
  • 165
1

Following the steps that works for me:

Install jquery npm install jquery

Install ts type npm install @types/jquery

Add jquery.min.js in your .angular-cli.json:

"scripts": [
   "../node_modules/jquery/dist/jquery.min.js"
]

Create a service to JQuery with the Token, Provider and Factory:

import { InjectionToken } from '@angular/core';
import * as $ from 'jquery';

export const JQUERY_TOKEN = new InjectionToken<JQueryStatic>('jquery');

export function jQueryFactory() {
    return $;
}

export const JQUERY_PROVIDER = { provide: JQUERY_TOKEN, useFactory: jQueryFactory };

Add the Provider in Module:

@NgModule({
  declarations: [
    ...
  ],
  providers: [
    JQUERY_PROVIDER,
    ...
  ]
})

Use DI in any component:

  constructor(
    @Inject(JQUERY_TOKEN) private $: JQueryStatic
  )

Be happy :D

this.$('body').css('background-color', 'red')
Leonardo Oliveira
  • 1,349
  • 1
  • 12
  • 14
1

Easiest and Shortest way possible to use jQuery in Angular 2/4

1st Step

From index.html

my-test-project\src\index.html

Type jQuery cdn below app-root tag.

...
<body>
  <app-root></app-root>
  <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</body>
...

2nd Step

my-test-project\src\app\test\test.component.ts

Go to your desired components .ts script.

import { Component, OnInit } from '@angular/core';

// this line will allow you to use jQuery
declare var $: any;

@Component({
  ...
})

3rd Step

my-test-project\src\app\test\test.component.ts

Test jQuery by logging 'I<3Cats' inside jQuery syntax $(() => { /* content here */ }).

export class TestComponent implements OnInit {

  constructor() { }

  ngOnInit() {
    $(() => {
      console.log('hello there!');
    });
  }

}

You can also use this technique with other javscript libraries. I don't know if this is safe but will sure help you. quite

flyingpluto7
  • 1,079
  • 18
  • 20
1

i had an issue with jquery not working on bootstrap navbar and solved like this...

import { Component, OnInit, AfterViewInit, ElementRef } from '@angular/core';
//declare var $: any; //old code..

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit, AfterViewInit {

  constructor(private elem: ElementRef) { }

  ngOnInit() {
  }
  ngAfterViewInit() {
    this.elem.nativeElement.querySelectorAll('.navbar-nav>li>a').forEach((el) => {
      el.addEventListener('click', () => {
        this.elem.nativeElement.querySelector('.navbar-toggler').classList.toggle('collapsed');
        this.elem.nativeElement.querySelector('.navbar-collapse').classList.toggle('show');
      });
    })

    //old code...
    // $('.navbar-nav>li>a').on('click', function () {
    //   $('.navbar-collapse').collapse('hide');
    // });
  }

}
Judson Terrell
  • 4,204
  • 2
  • 29
  • 45
0

Not sure what slideToggle() is doing, but FYI in Angular if you added #ref to h2.. you can then add

@ViewChild('ref')
h2El:Element;

in Typescript associated to the HTML. to do equivalent of $("#showAppinfo")..

If you used this in the HTML

<h2 #ref (click)="handler()">...</h2>

you'd have click handler.. so in Typescript add

handler() {
 this.h2El.slideToggle();
}
JGFMK
  • 8,425
  • 4
  • 58
  • 92
  • Thanks for the answer, slideToogle() is a jquery function I tried to do the way you said but I get error on `this.h2El.slideToggle();` it Says `[ts] Property 'slideToggle' does not exist on type 'Element'..` seems like i can't use jquery on elements like this.. – Vasilis Michail Jul 23 '17 at 22:29
  • @Zekelonas I think `$(event.target).slideToggle();` would be more appropriate. But if you can't use Jquery at all, then this doesn't matter... – Zze Jul 23 '17 at 22:31
  • Element is an Interface. There are interfaces with varying levels of specificity. There is a more complete list here: https://developer.mozilla.org/en-US/docs/Web/API For example, HTMLDivElement. In Typescript you can cast variables with either of these syntaxes: elDiv as HTMLDivElement or elDiv Sometimes that gives you the ability to call a method. But I suspect JQuery is embellishing the underlying interface prototypes to add slideToggle(). So you will probably still need jQuery at some point in your code. – JGFMK Jul 24 '17 at 08:34
0

your onInit method was inside the constructor, try it in the following way

constructor(db: AngularFireDatabase, public authService: AuthService, public afAuth: AngularFireAuth) {
    $(document).ready(function () {
        $("#showAppinfo").click(function () {
            $("#appinfo").slideToggle();
        });
    });

}
ngOnInit() { }}