@@ -11,7 +11,6 @@ import {
11
11
EventEmitter ,
12
12
Inject ,
13
13
Input ,
14
- isDevMode ,
15
14
IterableChangeRecord ,
16
15
IterableChanges ,
17
16
IterableDiffer ,
@@ -57,6 +56,14 @@ import { NguWindowScrollListener } from './ngu-window-scroll-listener';
57
56
58
57
type DirectionSymbol = '' | '-' ;
59
58
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
+
60
67
@Component ( {
61
68
selector : 'ngu-carousel' ,
62
69
templateUrl : 'ngu-carousel.component.html' ,
@@ -81,16 +88,26 @@ export class NguCarousel<T>
81
88
82
89
private _arrayChanges : IterableChanges < { } > | null = null ;
83
90
84
- @Input ( 'dataSource' )
85
- get dataSource ( ) : any {
91
+ @Input ( )
92
+ get dataSource ( ) : NguCarouselDataSource {
86
93
return this . _dataSource ;
87
94
}
88
- set dataSource ( data : any ) {
95
+ set dataSource ( data : NguCarouselDataSource ) {
89
96
if ( data ) {
90
97
this . _switchDataSource ( data ) ;
91
98
}
92
99
}
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 [ ] = [ ] ;
94
111
95
112
private _defaultNodeDef : NguCarouselDefDirective < any > | null ;
96
113
@@ -156,7 +173,7 @@ export class NguCarousel<T>
156
173
return this . _trackByFn ;
157
174
}
158
175
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 ) {
160
177
console . warn ( `trackBy must be a function, but received ${ JSON . stringify ( fn ) } .` ) ;
161
178
}
162
179
this . _trackByFn = fn ;
@@ -181,13 +198,13 @@ export class NguCarousel<T>
181
198
}
182
199
183
200
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 ) ) ;
187
204
}
188
205
189
206
ngDoCheck ( ) {
190
- this . _arrayChanges = this . _dataDiffer . diff ( this . dataSource ) ! ;
207
+ this . _arrayChanges = this . _dataDiffer . diff ( this . _unwrappedData ) ! ;
191
208
if ( this . _arrayChanges && this . _defDirectives ) {
192
209
this . _observeRenderChanges ( ) ;
193
210
}
@@ -210,8 +227,9 @@ export class NguCarousel<T>
210
227
}
211
228
212
229
dataStream
213
- ?. pipe ( takeUntil ( this . _intervalController$ ) , takeUntil ( this . _destroy$ ) )
230
+ ?. pipe ( takeUntil ( merge ( this . _intervalController$ , this . _destroy$ ) ) )
214
231
. subscribe ( data => {
232
+ this . _unwrappedData = data ;
215
233
this . renderNodeChanges ( data ) ;
216
234
this . isLast = this . _pointIndex === this . currentSlide ;
217
235
} ) ;
@@ -331,8 +349,6 @@ export class NguCarousel<T>
331
349
ngOnDestroy ( ) {
332
350
this . _hammertime ?. destroy ( ) ;
333
351
this . _destroy$ . next ( ) ;
334
- this . carouselLoad . complete ( ) ;
335
- this . onMove . complete ( ) ;
336
352
}
337
353
338
354
/** Get Touch input */
@@ -495,7 +511,7 @@ export class NguCarousel<T>
495
511
496
512
/** Init carousel point */
497
513
private _carouselPoint ( ) : void {
498
- const Nos = this . dataSource . length - ( this . items - this . slideItems ) ;
514
+ const Nos = this . _unwrappedData . length - ( this . items - this . slideItems ) ;
499
515
this . _pointIndex = Math . ceil ( Nos / this . slideItems ) ;
500
516
const pointers : number [ ] = [ ] ;
501
517
@@ -540,7 +556,7 @@ export class NguCarousel<T>
540
556
break ;
541
557
case this . _pointIndex - 1 :
542
558
this . _btnBoolean ( 0 , 1 ) ;
543
- slideremains = this . dataSource . length - this . items ;
559
+ slideremains = this . _unwrappedData . length - this . items ;
544
560
break ;
545
561
default :
546
562
this . _btnBoolean ( 0 , 0 ) ;
@@ -653,7 +669,7 @@ export class NguCarousel<T>
653
669
const MoveSlide = currentSlideD + this . slideItems ;
654
670
this . _btnBoolean ( 0 , 1 ) ;
655
671
if ( this . currentSlide === 0 ) {
656
- currentSlide = this . dataSource . length - this . items ;
672
+ currentSlide = this . _unwrappedData . length - this . items ;
657
673
itemSpeed = 400 ;
658
674
this . _btnBoolean ( 0 , 1 ) ;
659
675
} else if ( this . slideItems >= MoveSlide ) {
@@ -671,10 +687,10 @@ export class NguCarousel<T>
671
687
this . _carouselScrollTwo ( Btn , currentSlide , itemSpeed ) ;
672
688
} else if ( Btn === 1 && ( ( ! this . loop && ! this . isLast ) || this . loop ) ) {
673
689
if (
674
- this . dataSource . length <= this . currentSlide + this . items + this . slideItems &&
690
+ this . _unwrappedData . length <= this . currentSlide + this . items + this . slideItems &&
675
691
! this . isLast
676
692
) {
677
- currentSlide = this . dataSource . length - this . items ;
693
+ currentSlide = this . _unwrappedData . length - this . items ;
678
694
this . _btnBoolean ( 0 , 1 ) ;
679
695
} else if ( this . isLast ) {
680
696
currentSlide = 0 ;
@@ -720,7 +736,7 @@ export class NguCarousel<T>
720
736
this . _setStyle ( this . _nguItemsContainer . nativeElement , 'transition' , `` ) ;
721
737
}
722
738
723
- this . itemLength = this . dataSource . length ;
739
+ this . itemLength = this . _unwrappedData . length ;
724
740
this . _transformStyle ( currentSlide ) ;
725
741
this . currentSlide = currentSlide ;
726
742
this . onMove . emit ( this ) ;
@@ -773,7 +789,7 @@ export class NguCarousel<T>
773
789
/** this will trigger the carousel to load the items */
774
790
private _carouselLoadTrigger ( ) : void {
775
791
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 &&
777
793
this . carouselLoad . emit ( this . currentSlide ) ;
778
794
}
779
795
}
@@ -944,4 +960,6 @@ export class NguCarousel<T>
944
960
} )
945
961
) ;
946
962
}
963
+
964
+ static ngAcceptInputType_dataSource : NguCarouselDataSource ;
947
965
}
0 commit comments