Skip to content
This repository was archived by the owner on Apr 20, 2018. It is now read-only.

Commit 238025a

Browse files
Fixing first/last/elementat
1 parent bb018c8 commit 238025a

27 files changed

+1159
-440
lines changed

dist/rx.aggregates.js

Lines changed: 100 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -499,25 +499,31 @@
499499
};
500500

501501
/**
502-
* Returns the element at a specified index in a sequence or undefined if not found.
503-
* @example
504-
* var res = source.elementAt(5);
502+
* Returns the element at a specified index in a sequence or default value if not found.
505503
* @param {Number} index The zero-based index of the element to retrieve.
504+
* @param {Any} [defaultValue] The default value to use if elementAt does not find a value.
506505
* @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
507506
*/
508-
observableProto.elementAt = function (index) {
507+
observableProto.elementAt = function (index, defaultValue) {
509508
if (index < 0) { throw new ArgumentOutOfRangeError(); }
510509
var source = this;
511510
return new AnonymousObservable(function (o) {
512511
var i = index;
513-
return source.subscribe(function (x) {
514-
if (i-- === 0) {
515-
o.onNext(x);
516-
o.onCompleted();
517-
}
518-
}, function (e) { o.onError(e); }, function () {
519-
o.onNext(undefined);
520-
o.onCompleted();
512+
return source.subscribe(
513+
function (x) {
514+
if (i-- === 0) {
515+
o.onNext(x);
516+
o.onCompleted();
517+
}
518+
},
519+
function (e) { o.onError(e); },
520+
function () {
521+
if (defaultValue === undefined) {
522+
o.onError(new ArgumentOutOfRangeError());
523+
} else {
524+
o.onNext(defaultValue);
525+
o.onCompleted();
526+
}
521527
});
522528
}, source);
523529
};
@@ -549,41 +555,99 @@
549555

550556
/**
551557
* Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
552-
* @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence.
553-
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
554558
* @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
555559
*/
556-
observableProto.first = function (predicate, thisArg, defaultValue) {
557-
if (isFunction(predicate)) { return this.filter(predicate, thisArg).first(defaultValue); }
558-
var source = this;
560+
observableProto.first = function () {
561+
var obj = {}, source = this;
562+
if (typeof arguments[0] === 'object') {
563+
obj = arguments[0];
564+
} else {
565+
obj = {
566+
predicate: arguments[0],
567+
thisArg: arguments[1],
568+
defaultValue: arguments[2]
569+
};
570+
}
571+
if (isFunction (obj.predicate)) {
572+
var fn = obj.predicate;
573+
obj.predicate = bindCallback(fn, obj.thisArg, 3);
574+
}
559575
return new AnonymousObservable(function (o) {
560-
return source.subscribe(function (x) {
561-
o.onNext(x);
562-
o.onCompleted();
563-
}, function (e) { o.onError(e); }, function () {
564-
o.onNext(defaultValue);
565-
o.onCompleted();
566-
});
576+
var i = 0;
577+
return source.subscribe(
578+
function (x) {
579+
if (obj.predicate) {
580+
var res = tryCatch(obj.predicate)(x, i++, source);
581+
if (res === errorObj) { return o.onError(res.e); }
582+
if (res) {
583+
o.onNext(x);
584+
o.onCompleted();
585+
}
586+
} else if (!obj.predicate) {
587+
o.onNext(x);
588+
o.onCompleted();
589+
}
590+
},
591+
function (e) { o.onError(e); },
592+
function () {
593+
if (obj.defaultValue === undefined) {
594+
o.onError(new EmptyError());
595+
} else {
596+
o.onNext(obj.defaultValue);
597+
o.onCompleted();
598+
}
599+
});
567600
}, source);
568601
};
569602

570603
/**
571604
* Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
572-
* @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence.
573-
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
574605
* @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
575606
*/
576-
observableProto.last = function (predicate, thisArg) {
577-
if (isFunction(predicate)) { return this.filter(predicate, thisArg).last(); }
578-
var source = this;
607+
observableProto.last = function () {
608+
var obj = {}, source = this;
609+
if (typeof arguments[0] === 'object') {
610+
obj = arguments[0];
611+
} else {
612+
obj = {
613+
predicate: arguments[0],
614+
thisArg: arguments[1],
615+
defaultValue: arguments[2]
616+
};
617+
}
618+
if (isFunction (obj.predicate)) {
619+
var fn = obj.predicate;
620+
obj.predicate = bindCallback(fn, obj.thisArg, 3);
621+
}
579622
return new AnonymousObservable(function (o) {
580-
var value, seenValue = false;
581-
return source.subscribe(function (x) {
582-
value = x;
583-
}, function (e) { o.onError(e); }, function () {
584-
o.onNext(value);
585-
o.onCompleted();
586-
});
623+
var value, seenValue = false, i = 0;
624+
return source.subscribe(
625+
function (x) {
626+
if (obj.predicate) {
627+
var res = tryCatch(obj.predicate)(x, i++, source);
628+
if (res === errorObj) { return o.onError(res.e); }
629+
if (res) {
630+
seenValue = true;
631+
value = x;
632+
}
633+
} else if (!obj.predicate) {
634+
seenValue = true;
635+
value = x;
636+
}
637+
},
638+
function (e) { o.onError(e); },
639+
function () {
640+
if (seenValue) {
641+
o.onNext(value);
642+
o.onCompleted();
643+
}
644+
else if (obj.defaultValue === undefined) {
645+
o.onError(new EmptyError());
646+
} else {
647+
o.onNext(obj.defaultValue);
648+
o.onCompleted();
649+
}
650+
});
587651
}, source);
588652
};
589653

dist/rx.aggregates.map

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)