Kotlin Stream usage - kotlin

I have a code like below
items.forEach { item ->
request += getDetails(item.propertyId, item.destinationIds)
count++
if( count == bulkSize) {
save(request)
request = ""
count = 0
}
}
if(!request.isEmpty()) {
save(request)
}
How can I use streaming api to make the code less verbose ?

You can do it like this:
items.chunked(bulkSize) { chunk ->
save(chunk.joinToString(separator = "") { item ->
getDetails(item.propertyId, item.destinationIds)
})
}

Related

my code print error even the input is correct

This is origin code
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
if (ruleAttributes.firstOrNull { ruleAttribute -> ruleAttribute == destinationField } == null) {
addValidationError(RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH, configTypeBuilder.destinationField, NOT_EXIST_CONSTRAINT)
}
}
I modify the code, just add the invalid value to a list, and then print them, but now when I enter valid destinationField after invalid destinationField, it will still show the error message, I don't know what's going on
val invalidDestination = hashSetOf<String>()
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}
}
if (invalidDestination.size > 0) {
addValidationError(
"$RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH $NOT_EXIST_CONSTRAINT",
DESTINATION,
"$ADD_TAX_ENGINE_ATTRIBUTE_FIELDS $invalidDestination"
)
}
}
If your goal is to show error message only if there are no valid destinations, you need to add one more condition to your if statement. If not please clarify your question and post the whole function
Condition example:
var foundValid = false
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}else {
foundValid = true
break //if you need invalidDestination list for later remove this break
}
}
if (invalidDestination.size > 0 && !foundValid) {
...
}

How to get data using Add-in program from Office document without metadata(i.e. creation time)?

There's a function which retrieves document of PDF format byte by byte:
Office.initialize = function (reason) {
$(document).ready(function () {
// If not using Word 2016
if (!Office.context.requirements.isSetSupported('WordApi', '1.1')) {
$('#hash-button-text').text("Not supported!");
return;
}
//$('#hash-button').click(calculate_hash);
$('#btn').click(getFile);
});
};
function getFile() {
Office.context.document.getFileAsync(Office.FileType.Pdf, { sliceSize: 99 },
function (result) {
if (result.status == "succeeded") {
var file = result.value;
var sliceCount = file.sliceCount;
var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
getSliceAsync(file, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}
else {
console.log("Error");
}
}
);
}
function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
file.getSliceAsync(nextSlice, function (sliceResult) {
if (sliceResult.status == "succeeded") {
if (!gotAllSlices) { // Failed to get all slices, no need to continue.
return;
}
docdataSlices[sliceResult.value.index] = sliceResult.value.data;
if (++slicesReceived == sliceCount) {
file.closeAsync();
console.log("Done: ", docdataSlices);
}
else {
getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}
}
else {
gotAllSlices = false;
file.closeAsync();
console.log("getSliceAsync Error:", sliceResult.error.message);
}
});
}
So, close to ~1800 byte there are bytes like "CreationDate(D:20190218150353+02'00..." which are unnecessary in our case.
It retrieves the whole PDF file which consists meta, but is it possible to get it without it?
Best regards
The document.getFileAsync method will always return the entire document (including metadata); it's not possible to make it return anything less than the entire document.

QZ TRAY PRINITING ORDER NOT IN SEQ

I'm trying to print qz tray from javascript.
I have barcode with number in ascending order 1,2,3,4, 5 and so on.
I looping the seq correctly . but when printed out, it was not in order.
setTimeout("directPrint2()",1000);
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function directPrint2(){
var data;
var xhttp;
var v_carton = "' || x_str_carton ||'";
var carton_arr = v_carton.split('','');
var v1 = "' ||
replace(x_zebra_printer_id, '\', '|') ||
'".replace(/\|/g,"\\");
if(v1 == ""){
alert("Please setup ZPL Printer");
}
else{
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
data = [ toNative(this.responseText) ];
printZPL(data, v1);
}
};
for (var j = 0; j < carton_arr.length; j++){
var url = "' || x_wms_url ||
'WWW_URL.direct_print_label?in_carton_no="+toValidStr(carton_arr[j]);
xhttp.open("GET", url, false);
xhttp.send();
sleep(5000);
}
}
};
',
'javascript'
What's missing from your example:
I do not see any looping logic in the example calling the printZPL function,
printZPL isn't a QZ Tray function and you're missing the code snippet which it calls. Usually this would be qz.print(config, data);.
Regardless of the missing information, the qz.print(...) API is ES6/Promise/A+ based meaning if you want to call qz.print multiple times in a row you need to use a Promise-compatible technique. (e.g. .then(...) syntax) between your print calls as explained in the Chaining Requests guide.
To avoid this, you can concatenate all ZPL data into one large data array. Be careful not to spool too much data at once.
If you know exactly how many jobs you'll be appending, you can hard-code the promise chain:
qz.websocket.connect()
.then(function() {
return qz.printers.find("zebra"); // Pass the printer name into the next Promise
})
.then(function(printer) {
var config = qz.configs.create(printer); // Create a default config for the found printer
var data = ['^XA^FO50,50^ADN,36,20^FDRAW ZPL EXAMPLE^FS^XZ']; // Raw ZPL
return qz.print(config, data);
})
.catch(function(e) { console.error(e); });
Finally, if you do NOT know in advanced how many calls to qz.print(...) you can use a Promise loop as explained in the Promise Loop guide.
function promiseLoop() {
var data = [
"^XA\n^FO50,50^ADN,36,20^FDPRINT 1 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 2 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 3 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 4 ^FS\n^XZ\n"
];
var configs = [
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" }
];
var chain = [];
for(var i = 0; i < data.length; i++) {
(function(i_) {
//setup this chain link
var link = function() {
return qz.printers.find(configs[i_].printer).then(function(found) {
return qz.print(qz.configs.create(found), [data[i_]]);
});
};
chain.push(link);
})(i);
//closure ensures this promise's concept of `i` doesn't change
}
//can be .connect or `Promise.resolve()`, etc
var firstLink = new RSVP.Promise(function(r, e) { r(); });
var lastLink = null;
chain.reduce(function(sequence, link) {
lastLink = sequence.then(link);
return lastLink;
}, firstLink);
//this will be the very last link in the chain
lastLink.catch(function(err) {
console.error(err);
});
}
Note: The Promise Loop is no longer needed in QZ Tray 2.1. Instead, since 2.1, an array of config objects and data arrays can be provided instead.

check the status of the app moving or stationary

i want track my app status, i.e app is moving or stationary, I am using this module for location
https://github.com/mauron85/react-native-background-geolocation
for check the status of location i used this function
BackgroundGeolocation.on('stationary', (stationaryLocation) => {
console.log("stationaryLocation:"+JSON.stringify(stationaryLocation))
});
but it is not showing any response when i am stationary, can any one give me suggestion that how to resolve this.
Any help much appreciated.
Instead of using GeoLocation, you can use CMMotionActivityManager to track this.
public func getCurrentActivity(onRun:#escaping (_ activity: String?) -> Void) {
if(CMMotionActivityManager.isActivityAvailable()){
let mainQ = OperationQueue.main
self.activityManager?.startActivityUpdates(to: mainQ, withHandler: { (data: CMMotionActivity!) -> Void in
DispatchQueue.main.async(execute: {
var action = ""
if(data.stationary == true){
action = "Stationary"
} else if (data.walking == true){
action = "Walking"
} else if (data.running == true){
action = "Running"
} else if (data.automotive == true){
action = "Automotive"
} else if (data.cycling == true){
action = "cycling"
} else {
action = "Stationary"
}
onRun(action)
})
})
}
}

RxSwift combine observable with conditional

I'm trying to combine observables and I want them to run in sequence (e.g., perform step 1, if some condition is met then perform step 2, if some condition is met then perform step 3). The only way I've found to do this is to add the conditions to each step, which I'm not a fan of: Here's a sample of my current solution:
enum Status {
case unknown, exists, missing
}
func refresh() -> Observable<Status> {
return checkLocalStatus()
.flatMapLatest { $0 == .exists ? Observable.just($0) : self.attemptRemoteStatusOverride() }
.flatMapLatest { $0 == .exists ? Observable.just($0) : self.attemptRemoteStatusUpdate() }
}
private func checkLocalStatus() -> Observable<Status> {
return Observable.create { observer in
// Regarding Maxim Volgin's comment, here I'm converting a closure to an
// observable... why not use Observable.create?
self.cache.status { (status) in
guard status != .exists else {
observer.onNext(status) // .exists
observer.onCompleted()
}
/* I don't want this condition to be here */
if ignoreRemote {
// status is !exists and we should ignore remote, throw error
observer.onError(Errors.remoteDisabled)
}
observer.onNext(.missing)
observer.onCompleted()
}
}
}
private func attemptRemoteStatusOverride() -> Observable<Status> {
return remote.statusOverride()
}
private func attemptRemoteStatusUpdate() -> Observable<Status> {
return Observable.create { observer in
// Regarding Maxim Volgin's comment, here I'm converting a closure to an
// observable... why not use Observable.create?
self.remote.updateStatus { (status, error) in
guard error == nil else {
observer.onError(error!)
}
observer.onNext(status)
observer.onCompleted()
}
}
}
I'd like to do something like:
func refresh() -> Observable<Status> {
return checkLocalStatus()
.if({ $0 != .exists && !ignoreRemote },
then: { self.attemptRemoteStatusOverride() },
else: { return $0 })
.if({ $0 != .exists },
then: { self.attemptRemoteStatusUpdate() },
else: { return $0 })
}
or
func refresh() -> Observable<Status> {
return checkLocalStatus()
.flatMapLatest(if: { $0 != .exists && !ignoreRemote }) { self.attemptRemoteStatusOverride() }
.flatMapLatest(if: { $0 != .exists }) { self.attemptRemoteStatusUpdate() }
}
I haven't been able to find anything like what I'm attempting, so I assume I'm going about this wrong. Does anyone have suggestions or alternatives on how to go about this route of combining observables? I've seen examples using combineLatest and returning some results based on the result of something else, but I want to perform each step only if a condition is met. combineLatest would perform each step (every time) and then I would return the result(s) of some steps based on the output of other steps. I also started looking into writing a custom operator, but can't figure a way to do it.
Update: I've changed to the following and plan to write a method to remove duplication:
func refresh() -> Observable<Status> {
return checkLocalStatus()
.flatMapLatest { status -> Observable<Status>
guard status != .exists && !ignoreRemote else {
return Observable.just(status)
}
return self.attemptRemoteStatusOverride()
}
.flatMapLatest { status -> Observable<Status>
guard status != .exists && !ignoreRemote else {
return Observable.just(status)
}
return self.attemptRemoteStatusUpdate()
}
}
Maybe you need some version of flatMapLatest function with conditions? You can make some function that does what you want with the syntax you want:
extension Observable {
func flatMapLatest(condition: #escaping (E) -> Bool, then: #escaping (E) -> Observable, otherwise: #escaping () -> Observable) -> Observable {
let observable = self.shareReplayLatestWhileConnected()
let observableCondition = observable.map({ condition($0) }).shareReplayLatestWhileConnected()
let observableThen: Observable<E> = observableCondition
.filter({ $0 })
.withLatestFrom(observable)
.flatMapLatest({ then($0) })
.shareReplayLatestWhileConnected()
let observableOtherwise: Observable<E> = observableCondition
.filter({ !$0 })
.withLatestFrom(observable)
.flatMapLatest({ _ in otherwise() })
.shareReplayLatestWhileConnected()
return Observable<Observable<E>>
.from([observableThen, observableOtherwise])
.merge()
}
}
and use it
func refresh() -> Observable<Status> {
let condition = { (status: Status) -> Bool in
return status == .exists
}
let then = { (status: Status) -> Observable<Status> in
return Observable.just(status)
}
return checkLocalStatus()
.flatMapLatest(condition: condition, then: then, otherwise: self.attemptRemoteStatusOverride)
.flatMapLatest(condition: condition, then: then, otherwise: self.attemptRemoteStatusUpdate)
}