@@ -11,7 +11,6 @@ import {
1111 EventEmitter ,
1212 Inject ,
1313 Input ,
14- isDevMode ,
1514 IterableChangeRecord ,
1615 IterableChanges ,
1716 IterableDiffer ,
@@ -57,6 +56,14 @@ import { NguWindowScrollListener } from './ngu-window-scroll-listener';
5756
5857type DirectionSymbol = '' | '-' ;
5958
59+ type NguCarouselDataSource = Observable < any [ ] > | any [ ] | null | undefined ;
60+
61+ // This will be provided through Terser global definitions by Angular CLI.
62+ // This is how Angular does tree-shaking internally.
63+ declare const ngDevMode : boolean ;
64+
65+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode ;
66+
6067@Component ( {
6168 selector : 'ngu-carousel' ,
6269 templateUrl : 'ngu-carousel.component.html' ,
@@ -81,16 +88,26 @@ export class NguCarousel<T>
8188
8289 private _arrayChanges : IterableChanges < { } > | null = null ;
8390
84- @Input ( 'dataSource' )
85- get dataSource ( ) : any {
91+ @Input ( )
92+ get dataSource ( ) : NguCarouselDataSource {
8693 return this . _dataSource ;
8794 }
88- set dataSource ( data : any ) {
95+ set dataSource ( data : NguCarouselDataSource ) {
8996 if ( data ) {
9097 this . _switchDataSource ( data ) ;
9198 }
9299 }
93- private _dataSource : any ;
100+ private _dataSource : NguCarouselDataSource = null ;
101+
102+ /**
103+ * `_dataSource` allows multiple values to be set considering nullable and
104+ * observable values. We shouldn't try to get `_dataSource.length` since it
105+ * might be `null|undefined` which will throw an error that property doesn't
106+ * exist on `undefined`. It will also always equal `undefined` on observable.
107+ * We should wait until the observable is unwrapped and then check the length
108+ * of the actual unwrapped data.
109+ */
110+ private _unwrappedData : any [ ] = [ ] ;
94111
95112 private _defaultNodeDef : NguCarouselDefDirective < any > | null ;
96113
@@ -156,7 +173,7 @@ export class NguCarousel<T>
156173 return this . _trackByFn ;
157174 }
158175 set trackBy ( fn : TrackByFunction < T > ) {
159- if ( isDevMode ( ) && fn != null && typeof fn !== 'function' && console && console . warn ) {
176+ if ( NG_DEV_MODE && fn != null && typeof fn !== 'function' && console ? .warn ) {
160177 console . warn ( `trackBy must be a function, but received ${ JSON . stringify ( fn ) } .` ) ;
161178 }
162179 this . _trackByFn = fn ;
@@ -181,13 +198,13 @@ export class NguCarousel<T>
181198 }
182199
183200 ngOnInit ( ) {
184- this . _dataDiffer = this . _differs . find ( [ ] ) . create ( ( _i : number , item : any ) => {
185- return this . trackBy ? this . trackBy ( _i , item ) : item ;
186- } ) ;
201+ this . _dataDiffer = this . _differs
202+ . find ( [ ] )
203+ . create ( ( index : number , item : any ) => ( this . trackBy ? this . trackBy ( index , item ) : item ) ) ;
187204 }
188205
189206 ngDoCheck ( ) {
190- this . _arrayChanges = this . _dataDiffer . diff ( this . dataSource ) ! ;
207+ this . _arrayChanges = this . _dataDiffer . diff ( this . _unwrappedData ) ! ;
191208 if ( this . _arrayChanges && this . _defDirectives ) {
192209 this . _observeRenderChanges ( ) ;
193210 }
@@ -210,8 +227,9 @@ export class NguCarousel<T>
210227 }
211228
212229 dataStream
213- ?. pipe ( takeUntil ( this . _intervalController$ ) , takeUntil ( this . _destroy$ ) )
230+ ?. pipe ( takeUntil ( merge ( this . _intervalController$ , this . _destroy$ ) ) )
214231 . subscribe ( data => {
232+ this . _unwrappedData = data ;
215233 this . renderNodeChanges ( data ) ;
216234 this . isLast = this . _pointIndex === this . currentSlide ;
217235 } ) ;
@@ -331,8 +349,6 @@ export class NguCarousel<T>
331349 ngOnDestroy ( ) {
332350 this . _hammertime ?. destroy ( ) ;
333351 this . _destroy$ . next ( ) ;
334- this . carouselLoad . complete ( ) ;
335- this . onMove . complete ( ) ;
336352 }
337353
338354 /** Get Touch input */
@@ -495,7 +511,7 @@ export class NguCarousel<T>
495511
496512 /** Init carousel point */
497513 private _carouselPoint ( ) : void {
498- const Nos = this . dataSource . length - ( this . items - this . slideItems ) ;
514+ const Nos = this . _unwrappedData . length - ( this . items - this . slideItems ) ;
499515 this . _pointIndex = Math . ceil ( Nos / this . slideItems ) ;
500516 const pointers : number [ ] = [ ] ;
501517
@@ -540,7 +556,7 @@ export class NguCarousel<T>
540556 break ;
541557 case this . _pointIndex - 1 :
542558 this . _btnBoolean ( 0 , 1 ) ;
543- slideremains = this . dataSource . length - this . items ;
559+ slideremains = this . _unwrappedData . length - this . items ;
544560 break ;
545561 default :
546562 this . _btnBoolean ( 0 , 0 ) ;
@@ -653,7 +669,7 @@ export class NguCarousel<T>
653669 const MoveSlide = currentSlideD + this . slideItems ;
654670 this . _btnBoolean ( 0 , 1 ) ;
655671 if ( this . currentSlide === 0 ) {
656- currentSlide = this . dataSource . length - this . items ;
672+ currentSlide = this . _unwrappedData . length - this . items ;
657673 itemSpeed = 400 ;
658674 this . _btnBoolean ( 0 , 1 ) ;
659675 } else if ( this . slideItems >= MoveSlide ) {
@@ -671,10 +687,10 @@ export class NguCarousel<T>
671687 this . _carouselScrollTwo ( Btn , currentSlide , itemSpeed ) ;
672688 } else if ( Btn === 1 && ( ( ! this . loop && ! this . isLast ) || this . loop ) ) {
673689 if (
674- this . dataSource . length <= this . currentSlide + this . items + this . slideItems &&
690+ this . _unwrappedData . length <= this . currentSlide + this . items + this . slideItems &&
675691 ! this . isLast
676692 ) {
677- currentSlide = this . dataSource . length - this . items ;
693+ currentSlide = this . _unwrappedData . length - this . items ;
678694 this . _btnBoolean ( 0 , 1 ) ;
679695 } else if ( this . isLast ) {
680696 currentSlide = 0 ;
@@ -720,7 +736,7 @@ export class NguCarousel<T>
720736 this . _setStyle ( this . _nguItemsContainer . nativeElement , 'transition' , `` ) ;
721737 }
722738
723- this . itemLength = this . dataSource . length ;
739+ this . itemLength = this . _unwrappedData . length ;
724740 this . _transformStyle ( currentSlide ) ;
725741 this . currentSlide = currentSlide ;
726742 this . onMove . emit ( this ) ;
@@ -773,7 +789,7 @@ export class NguCarousel<T>
773789 /** this will trigger the carousel to load the items */
774790 private _carouselLoadTrigger ( ) : void {
775791 if ( typeof this . inputs . load === 'number' ) {
776- this . dataSource . length - this . load <= this . currentSlide + this . items &&
792+ this . _unwrappedData . length - this . load <= this . currentSlide + this . items &&
777793 this . carouselLoad . emit ( this . currentSlide ) ;
778794 }
779795 }
@@ -944,4 +960,6 @@ export class NguCarousel<T>
944960 } )
945961 ) ;
946962 }
963+
964+ static ngAcceptInputType_dataSource : NguCarouselDataSource ;
947965}
0 commit comments