3

I'm trying to get a Bootstrap 4 carousel working in my Angular 2 app. Specifically, I'm trying to replicate the full-width effect done here. I get as far as the last bit where I have to hook the element to the carousel:

$('.carousel').carousel({
  interval: 6000,
  pause: "false"
});

When I attempt to compile, I get the following error:

Error: Property 'carousel' does not exist on type 'JQuery'

I'm aware that there are the ng-bootstrap components, but I wasn't able to get the carousel there to be completely full-width in this way.

Here's my code (Typescript, CSS, HTML):

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

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

  constructor() { }

  ngOnInit() {
  }

  setupCarousel(): void {
    var $item = $('.carousel .item'); 
    var $wHeight = $(window).height();
    $item.eq(0).addClass('active');
    $item.height('400px'); 
    $item.addClass('full-screen');

    $('.carousel img').each(function() {
      var $src = $(this).attr('src');
      var $color = $(this).attr('data-color');
      $(this).parent().css({
        'background-image' : 'url(' + $src + ')',
        'background-color' : $color
      });
      $(this).remove();
    });

    $(window).on('resize', function (){
      $wHeight = $(window).height();
      $item.height($wHeight);
    });

    $('.carousel').carousel({  // <-- ERROR is on the .carousel
      interval: 6000,
      pause: "false"
    });    
  }
}
h3 {
  display: inline-block;
  padding: 10px;
}

.full-screen {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  height: 300px;
}
<div id="mycarousel" class="carousel slide" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators">
    <li data-target="#mycarousel" data-slide-to="0" class="active"></li>
    <li data-target="#mycarousel" data-slide-to="1"></li>
    <li data-target="#mycarousel" data-slide-to="2"></li>
    <li data-target="#mycarousel" data-slide-to="3"></li>
    <li data-target="#mycarousel" data-slide-to="4"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item">
        <img src="https://unsplash.it/2000/1250?image=397" data-color="lightblue" alt="First Image">
        <div class="carousel-caption">
            <h3>First Image</h3>
        </div>
    </div>
    <div class="item">
        <img src="https://unsplash.it/2000/1250?image=689" data-color="firebrick" alt="Second Image">
        <div class="carousel-caption">
            <h3>Second Image</h3>
        </div>
    </div>
    <div class="item">
        <img src="https://unsplash.it/2000/1250?image=675" data-color="violet" alt="Third Image">
        <div class="carousel-caption">
            <h3>Third Image</h3>
        </div>
    </div>
    <div class="item">
        <img src="https://unsplash.it/2000/1250?image=658" data-color="lightgreen" alt="Fourth Image">
        <div class="carousel-caption">
            <h3>Fourth Image</h3>
        </div>
    </div>
    <div class="item">
        <img src="https://unsplash.it/2000/1250?image=638" data-color="tomato" alt="Fifth Image">
        <div class="carousel-caption">
            <h3>Fifth Image</h3>
        </div>
    </div>
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#mycarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#mycarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

Here's my index.html file:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Website</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
        integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <div class="my-fluid-container">
    <div class="row">
      <div class="col-md-12 app-container">
        <app-root>Loading...</app-root>
      </div>
    </div>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.1/imagesloaded.pkgd.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"
          integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"
          integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"
          integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
</body>
</html>

Thanks for any help!

Community
  • 1
  • 1
Eddie
  • 1,228
  • 3
  • 17
  • 31

3 Answers3

7

Step 1. Make sure you have jQuery and Bootstrap.js mentioned in the scripts section of the angular-cli.json

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

Step 2. In your home-carousel.component.ts right after import { Component, OnInit } from '@angular/core'; add declare var $:any; like this:

import { Component, OnInit } from '@angular/core';
declare var $:any;

Step 3. Although not compulsory, but I find it safer to put jQuery and JS code inside ngOnInit() like this:

ngOnInit() {
    $('.carousel').carousel({
        interval: 2000
    });
}

I hope this works.

Donnie Ashok
  • 1,355
  • 1
  • 11
  • 26
  • 1
    For me `declare var $:any;` did the job while `import * as $ from 'jquery';` didn't – StinkyCat Sep 08 '18 at 15:43
  • The `scripts` additions caused my prod build to fail, but using only steps 2 and 3 got it working for me on angular 10 – brt Apr 01 '21 at 14:33
1

I had the same issue and was able to resolve it by changing

import * as $ from 'jquery';

to

declare var jQuery: any;

Looks like the first creates a new instance of jQuery; whereas, the second accesses the global instance which got the bootstrap functions(carousel, modal...etc) attached to it. You can confirm this by adding the following in your component class and toggling between the two import statements mentioned above.

console.log($.fn.carousel);
console.log($.fn.modal);

More on declare keyword: What does 'declare' do in 'export declare class Actions'?

About TypeScript import statement: https://www.typescriptlang.org/docs/handbook/modules.html

0

Your problem is that you did not import bootstrap or that you did not import it correctly. In your index.html make sure that you import bootstrap after jQuery like this:

<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"></script>

Not you should be able to use the carousel.

Deutro
  • 3,113
  • 4
  • 18
  • 26
  • I tried that, even though I believe I do have these referenced properly (first jquery then bootstrap), but it didn't make any difference. I still get the typescript error above. I'm not sure how that would help with typescript anyways, but I did give it a shot. Thanks – Eddie Feb 08 '17 at 19:27
  • Well, not in a comment I can't, it's too long. But I basically have copied the HTML exactly from the Codpen link I included in my original post - http://codepen.io/SitePoint/pen/ZbGwqe. I use the same CSS, and I have created a function called setupCarousel, into which I've copied all of the JS from that Codepen as well. At the bottom of the JS is where I call the carousel and attach it to the element using the classname to select it (".carousel"). I installed jquery and bootstrap through npm, and can confirm they are installed properly. – Eddie Feb 08 '17 at 19:38
  • U can edit your question and insert your code there. This will make it easier to help ya. – Deutro Feb 08 '17 at 19:41
  • Would you mind adding your index.html. I just tried to reproduce the error but for Materialize in my project and I get the exact same error if I remove the js file from Materialize. – Deutro Feb 08 '17 at 19:55
  • Ok, added index.html. – Eddie Feb 08 '17 at 19:57
  • Can u try to put the script files inside your tag? – Deutro Feb 08 '17 at 20:01
  • Yeah, that doesn't work either, and you really shouldn't have to put any script references in the head tag. I'm using Visual Studio Code to build this, and the error in in the Typescript itself. A reference position shouldn't make any difference to Typescript. It's a build error... It won't compile. – Eddie Feb 08 '17 at 20:03