Mongo result docs not store as object - java

I'm trying to get the results after executing a query and store it in a variable called "model".
db.collection.findOne({object},function(err,docs){
model["output"]= docs;
})
The above code stores model["output"] as "undefined". How do I get hold of this value?
Sorry there was not enough code.
So there are two files.
FILE1
dbStmtModel.insertRecords(collectionName, record).then(
function (results) {
console.log("results",results);
result = results;
}, function (err){
return err;
});
model[statement.output] = result;
FILE2
function insertRecords(operand1,operand2){
var deferred = q.defer();
db.collection(operand1).update(operand2,operand2,{upsert:true},function (err,docs) {
if(err) {
deferred.reject(err);
}
else {
deferred.resolve(docs);
}
});
return deferred.promise
}
So tried using promises, tried using async. Still do not seem to get the model store the output of the result of the query. Also, there are no errors, since the callback returns correctly and prints the results. I'm not sure I'm using promises correctly though, although the console statement seems to print the results correctly. Also I'm using mongojs and not mongoose over mongodb(since the schema here is dynamic), don't know if thats going to change anything.

First of all, check for the err param you're ignoring
There is no enough code to be sure, but I'm guessing you defined model before in the same scope you're calling findOne and just below that you try to use model['output'].
This won't work since findOne (as almost every mongodb driver method) is asynchronous, so it's unlikely for its callback to be called before you try to use model['output'].
There's no quick solution for your problem, you need to understand asynchronism. Checkout this answer.

db.collection.findOne({object},function(err,docs){
model["output"]= docs;
})
First - ill assume that your "model" object is defined. (It would throw that model is undefined, not model output)
Second, You're not checking for error, if there was error docs end up empty.
If still you've got Undefinded. There could be also error with model object. For instance - check if its even an object.
db.collection.findOne({object}, (err, docs) => {
if(err) {
return console.log(err)
}
model.output = docs;
}
Also! I'm just guessing but maybe you're trying to use it out of .findOne scope? What I mean - it is asynchronous call. So if you do something like this
db.collection.findOne({object}, (err, docs) => {
if(err) {
return console.log(err)
}
model.output = docs;
}
console.log(model.output);
then your model.output is undefined cause you call it before database returns data - it does not wait. You'll have to use callback (or promise) then.
callDB (object, cb) => {
db.collection.findOne(object, (err, docs) => {
if(err) {
return (err)
}
return (null, docs);
}
}
then you could call it
callDB({object}, (err, result) => {
model.result = result;
});
But be advised that your new call for function is still asynchronous. So still your model.result will work only inside of its scope.
// I've seen you've updated your question, but I'll leave it here.

First be sure that you are getting your results make a
console.log("RESULT",docs) if you getting your results then try below methods
As mongo query return doc which is a model schema that can not be modify.
Try this with lean it return document JSON object
var model={};
db.collection.findOne({object},function(err,docs){
model.output= docs;
}).lean(true);
OR
var result={}
db.collection.findOne({object},function(err,docs){
result.model.output = docs;
})

Related

How to Avoid Table Loading Stale Search Queries

I have a webapp which has performs a simple search via a REST endpoint. Each search has 0 or more arguments. How do I prevent this scenario?
User submits search request "A"
Before allowing "A" to return they modify their request and submit a new search request "B"
At this point the user expects to see the results for "B" but depending on what order the searches return either one may be displayed. How do I prevent the search results from "A" populating the table?
I am thinking about creating a hash from the search terms, sending the hash along with the search request, and comparing the hash in the return value to the hash of the most recently submitted search criteria, and only loading the request results if the hashes match.
I apologize if this question has been asked before, but I wasn't able to find it. I am using Angular 1.4 UI and a Java/Spring backend. I figure this might be a common problem with an established pattern.
You can decorate $http and add an abort method to the returned promise. This will allow you to check your promise in implementation and use the abort() to cancel the previous promise request (implementation example in the doc block below).
;(function(angular, undefined) {
angular.module('app.appConfigs')
.config(httpDecoratorConfig);
function httpDecoratorConfig($provide) {
$provide.decorator('$http', decorateHttpWithAbort);
}
/**
* decorate $http response promise with an abort function.
* use this on destroy where you want to abort the outstanding request made on
* a page before leaving the page.
*
* #example
var requestPromise = $http(reqConfig).then(...).catch(...).finally(...);
$onDestroy() {
requestPromise.abort();
}
*/
function decorateHttpWithAbort(_, $q, $delegate) {
var originalHttpService = $delegate;
function newHttpServiceConstructor(requestConfig) {
var canceller = $q.defer();
var proxyRequest = $q.defer();
var onAbortCallback = angular.noop;
// adding abortFn into request promise
proxyRequest.promise.abort = function abortFn() {
canceller.resolve();
};
// by using onAbort capture the callback function which will be called
// when the request is aborted, use this to perform cleanups.
proxyRequest.promise.onAbort = function onAbortFn(callback) {
onAbortCallback = callback;
return this;
};
// adding request canceller promise in the original request config.
requestConfig.timeout = canceller.promise;
originalHttpService(requestConfig).then(
function onSuccess() {
proxyRequest.resolve.apply(this, arguments);
},
function onError(resp) {
// don't resolve the abort response with error instead call provided
// on abort callback to give user a change to handle abort case.
// natively angular abort is resolved with error.
if (resp.status === -1) {
onAbortCallback();
return;
}
proxyRequest.reject.apply(this, arguments);
},
function onNotification() {
proxyRequest.notify.apply(this, arguments);
}
);
return proxyRequest.promise;
}
// inherit all derived methods from original $http like $get, $put etc
_.assign(newHttpServiceConstructor, originalHttpService);
return newHttpServiceConstructor;
}
})(angular);

How can I return boolean value using Optional.ifPresent

I have some problems with using Optional.ifPresent statement. I would like to reduce number of NullPointerExceptions, so I decided to use Optional values.
Also I am trying to avoid a ladder of if statements anti-pattern.
So I implemented Optional.isPresent statement. But it's not really that what I expected.
Please look at these listings:
This is a part of my service:
if (getAllComputerProducers().isPresent()) {
if (isComputerProducerAlreadyExist(computerProducer))
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
computerProducerRepository.save(computerProducer);
return new ResponseEntity<>(HttpStatus.CREATED);
getAllComputerProducers function looks like that:
private Optional<List<ComputerProducer>> getAllComputerProducers() {
return Optional.ofNullable(computerProducerRepository.findAll());
}
As you can see, this function returns Optional of List.
The isComputerProducerAlreadyExist function is implemented like that:
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer) {
return getAllComputerProducers()
.get()
.stream()
.anyMatch(producer -> producer.getProducerName()
.equalsIgnoreCase(computerProducer.getProducerName()));
}
It's so much code and I believe that it could be made simpler.
My target is to reduce code to one line command like:
getAllCimputerProducers().ifPresent(***and-here-some-anyMatch-boolean-function***)
but I can't insert there a function which returns something. How can I do it?
Regards to everyone :)
You could try something like
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
return this.getAllComputerProducers()
.map((List<ComputerProducer> computerProducers) -> computerProducers.stream()
.anyMatch(producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName())))
.orElse(Boolean.FALSE);
}
Or instead of loading all computer producers load only the ones using its name.
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
return computerProducerRepository.findByName(computerProducer.getProducerName()).isEmpty();
}
And as far as I know Spring supports also "exist" methods for repositories without even the need to load the Entity.
The following should work
Predicate<ComputerProducer> cpPredicate = producer -> producer.getProducerName()
.equalsIgnoreCase(computerProducer.getProducerName());
boolean compProdExists = getAllCimputerProducers()
.map(list -> list.stream()
.filter(cpPredicate)
.findFirst()))
.isPresent();
You can pass the computerProducer.getProducerName() to repository to get the existing record. Method name will be 'findByProducerName(String producerName)', if producerName has unique constraint, return type will be Optional<ComputerProducer>, else Optional<List<ComputerProducer>>. However, JPA returns empty list instead of null, so optional on list is not required.

Kotlin, Reactive programming : How to consume the value of one function output to another one

I am very new to Project reactor library and reactive programming with Kotlin, and trying to implement functions like flatmap, flatMapIterable, subscribe etc.
Now issue is I am trying to use the o/p of one function into another one using flatMapIterable, and after using I am trying to subscribe this, by passing the output of fist function and second one to another function of new class.
Now when I try to use the o/p of function 1, I am unable to see the value, I only see Mono<> or Flux<>.
Below is code snippet for more explanation
var result = employerService.getEmployee("Active") // return value is Mono<GetEmployeeStatusListResult>
result.flatMapIterable(GetEmployeeStatusListResult::emps)
.flatMap {
employerService.getUsersById(it.userId) // it is of type GetEmployeeStatusListResult.emps and value returned from employerService.getUsersById(it.userId) is of type GetUserResult class created
}.subscribe {
aService.createContact(result, it)
}
Now at line 4 I am getting expected userId out of it.userId, but when I inspect result at line 6, then I do not get the expected list of values, it just provides me MonomapFuesable, with mapper and source.
Can anyone please help me to understand what should I do, as my whole agenda is to pass the calculated value from line 1 and line 4 to line 6 function.
Please ask more question, if I haven't provided the required information, I am very new to this.
Thanks in advance !!
[UPDATE] : I have resolved the issue with the following way :
```
employerService.getEmployee("Active") // return value is Mono<GetEmployeeStatusListResult>
.flatMapIterable(GetEmployeeStatusListResult::emps)
.flatMap {
employerService.getUsersById(it.userId).map{x->Pair(it,x)} // it is of type GetEmployeeStatusListResult.emps and value returned from employerService.getUsersById(it.userId) is of type GetUserResult class created
}.subscribe {
aService.createContact(it.first, it.second)
}
```
It's a bit hard to know for sure from the information supplied above, but I think it looks like the call to employerService.getUsersById isn't returning a Publisher. From your comments I'm guessing it's returning an actual value, GetUserResult, rather than a Mono. Below is a mocked up set of classes which show the desired result, I believe. Maybe compare the below to what you've got and see if you can spot a difference?
data class Employee(val userId: String)
data class GetEmployeeStatusListResult(val emps: List<Employee>)
data class GetUserResult(val employee: Employee)
class EmployerService {
fun getEmployee(status: String) = Mono.just(GetEmployeeStatusListResult(listOf(Employee("a"))))
fun getUsersById(userId: String) = Mono.just(GetUserResult(Employee("a")))
}
fun test() {
val employerService = EmployerService()
employerService
.getEmployee("Active")
.flatMapIterable(GetEmployeeStatusListResult::emps)
.flatMap {
employerService.getUsersById(it.userId)
}.subscribe {
// Here "it" is a GetUserResult object
}
}
If, in the subscribe, you need both the initial value retrieved from the call to getEmployee and also the result of the call to getUsersById then you could wrap those two values in a Pair as shown below:
employerService
.getEmployee("Active")
.flatMapIterable(GetEmployeeStatusListResult::emps)
.flatMap { emp ->
employerService.getUsersById(emp.userId).map { emp to it }
}.subscribe {
// Here "it" is a Pair<Employee, GetUserResult>
}
employerService.getEmployee("Active") // return value is Mono<GetEmployeeStatusListResult>
.flatMapIterable(GetEmployeeStatusListResult::emps)
.flatMap {
employerService.getUsersById(it.userId).map{x->Pair(it,x)} // it is of type GetEmployeeStatusListResult.emps and value returned from employerService.getUsersById(it.userId) is of type GetUserResult class created
}.subscribe {
aService.createContact(it.first, it.second)
}
Adding pair function to fetch both the values and use it in subscribe block !!
Thanks everyone !!

Callback with parameters with Kotlin

I just started Kotlin so please be nice :)
I have a class that is responsible for fetching some data and notify the main activity that its need to update its UI.
So i have made a function in my DataProvider.kt :
fun getPeople(fromNetwork: Boolean, results: ((persons: Array<Person>, error: MyError?) -> Unit)) {
// do some stuff stuff
val map = hashMapOf(
"John" to "Doe",
"Jane" to "Smith"
)
var p = Person(map)
val persons: Array <Person> = arrayOf (p)
results(persons, null)
}
So i want to call this from my activity but i can't find the right syntax ! :
DataProvider.getPeople(
true,
results =
)
I have try many things but i just want to get my array of persons and my optional error so i can update the UI.
The goal is to perform async code in my data provider so my activity can wait for it.
Any ideas ? Thank you very much for any help.
This really depends on how you define the callback method. If you use a standalone function, use the :: operator. First (of course), I should explain the syntax:
(//these parenthesis are technically not necessary
(persons: Array<Person>, error: MyError?)//defines input arguments: an Array of Person and a nullable MyError
-> Unit//defines the return type: Unit is the equivalent of void in Java (meaning no return type)
)
So the method is defined as:
fun callback(persons: Array<CustomObject>, error: Exception?){
//Do whatever
}
And you call it like:
DataProvider.getPeople(
true,
results = this::callback
)
However, if you use anonymous callback functions, it's slightly different. This uses lambda as well:
getPeople(true, results={/*bracket defines a function. `persons, error` are the input arguments*/persons, error -> {
//do whatever
}})
Yes Kotlin has a great way of using callback functions which I will show you an example of how I use them below:
fun addMessageToDatabase(message: String, fromId: String, toId: String,
addedMessageSuccessHandler: () -> Unit,
addedMessageFailureHandler: () -> Unit) {
val latestMessageRef = mDatabase.getReference("/latest-messages/$fromId/$toId")
latestMessageRef.setValue(message).addOnSuccessListener {
latestMessageUpdateSuccessHandler.invoke()
}.addOnFailureListener {
latestMessageUpdateFailureHandler.invoke()
}
}
And finally you can utilise the new callbacks with the following code
databaseManager.updateLatestMessageForUsers(message, fromId, toId,
latestMessageUpdateSuccessHandler = {
// your success action
},
latestMessageUpdateFailureHandler = {
// your failure action
})
So basically when I successfully add a new row to my database I'm invoking a success or a failure response to the caller of the service. Hopefully this will help out someone.

rxjava2 - if else on Maybe

I am looking for what is the recommended practice in rxjava2 to handle a case where one flowable leads to conditional behaviors.
More concretely, I have a Maybe<String> for which I want to Update the String on the database if the String exists or, if it doesn't exists I want to create a new String and save it on the database.
I thought of the below but obviously it is not what I am looking for:
Maybe<String> source = Maybe.just(new String("foo")); //oversimplified source
source.switchIfEmpty(Maybe.just(new String("bar"))).subscribe(result ->
System.out.println("save to database "+result));
source.subscribe(result -> System.out.println("update result "+result));
The above obviously produces
save to database foo
update result foo
I tried also the below which gives the expected result but still feel it's... weird.
Maybe<String> source = Maybe.just(new String("foo")); //oversimplified source
source.switchIfEmpty(Maybe.just(new String("bar")).doOnSuccess(result ->
System.out.println("save to database "+result))).subscribe();
source.doOnSuccess(result -> System.out.println("update result "+result)).subscribe();
How can I have an action for when the result exists and when it doesn't exists? How is that use case supposed to be handled in rxjava2?
Update 01
I tried the below and it looks cleaner than what I came up with above. Note sure it is recommended rxjava2 practice however...
Maybe.just(new String("foo"))
.map(value -> Optional.of(value))
.defaultIfEmpty(Optional.empty())
.subscribe(result -> {
if(result.isPresent()) {
System.out.println("update result "+result);
}
else {
System.out.println("save to database "+"bar");
}
});
You have the isEmpty() operator that will return you Boolean if the Maybe source is empty or not, and then you can flatMap it and write a if else statement depending on that Boolean
This is a common pattern in our code as well, though in our case the choices are themselves async. You can't get quite the right semantic by simply composing flatMapX and switchIfEmpty (in either order), so I am curious why this isn't part of the API.
Here's what we're doing for now (this example for when the 2 options are both Completables, we have similar things for the other types as well):
public static <T> Completable flatMapCompletable(Maybe<T> target,
#ClosureParams(FirstParam.FirstGenericType.class)
Closure<? extends CompletableSource> completableSupplier,
Supplier<CompletableSource> emptySupplier) {
Maybe<T> result = target.cache();
return result.isEmpty().flatMapCompletable(empty -> {
if (empty) {
return emptySupplier.get();
} else {
return result.flatMapCompletable(completableSupplier::call);
}
});
}
We're using Groovy, so we package these up as extension methods. I'm not thrilled with the need to use cache() so I'm wondering if there is a better alternative. From looking at the code, an operator which basically combines flatMapX and switch looks like it wouldn't be too hard (but I feel like I'm missing something).
Try something like this. checkDB can return a Maybe or Single or whatever which emits either an optional or a wrapper Object.
checkDB(String)
.flatMap(s -> {
if (s.isPresent()) {
return updateDB(s.get());
} else {
return insertDB("new String");
}
})
There is an solution using the flatMap call with 3 params
fun addOrUpdate(message: LocalMessage): Single<LocalMessage> {
return getById(message.id) // returns Maybe
.flatMap(
Function {
update(message) // onSuccess update call returns Single
},
Function {
Single.error(it) // onError
},
Callable {
add(message) // onComplete add call returns Single
}
)
}
}
Or shorter version
fun addOrUpdate(message: LocalMessage): Single<LocalMessage> {
return getById(message.id) // returns Maybe
.flatMap(
{
update(message) // onSuccess update call returns Single
},
{
Single.error(it) // onError
},
{
add(message) // onComplete add call returns Single
}
)
}
}

Categories

Resources