Mar
Mar

Reputation: 443

How to check whether Optional value is null and how to pass it to other method?

I need to pass dateTs from rest controller class-method into getCars() method in the service class which will retrieve cars that were registered on the given timestamp date and if the timestamp dateTs(its Optional) is null then it will retrieve all cars. I think current implementation will not work since if dateTs is null then it can't be passed into getCars() which expects value of type Long. Where and how should I check if the dateTs is not null and how to pass corresponding value into getCars() and invoke appropriate method?

@GetMapping(value = "/get/cars")
public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
   
return ResponseEntity.ok(carService.getCars((Long) dateSt.get());
} 

Service class method:

public List<Car> getCars(Long dateSt) {
   List<Car> carList; 
  
   if(dateSt != null){
       carList = carReposistory.retrieveRegisteredCars(dateSt);}
   else{
      carList = carReposistory.retrieveAllCars();} 
       
   return carList;
}

Upvotes: 1

Views: 280

Answers (3)

Yassin Hajaj
Yassin Hajaj

Reputation: 21975

You usually don't want to pass Optionals as parameters, however I don't know if it applies to REST controllers. See this

Now that this is said, you should have two methods in your service, one for when it's present, one when it's absent.

Controller

@GetMapping(value = "/get/cars")
public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
    return ResponseEntity.ok(
               dateTs.map(carService::getRegisteredCars)
                     .orElseGet(carService::getAllCars)
           );
} 

Service

public List<Car> getRegisteredCars(Long dateSt) {
    return carReposistory.retrieveRegisteredCars(dateSt);
}

public List<Car> getAllCars() {
    return carReposistory.retrieveAllCars();
}

Upvotes: 2

user13510609
user13510609

Reputation:

Just a note: a Long can be null, so it can be passed to getCars(Long). It is a long that cannot be null, since it is a primitive.

The problem probably is that Optional#get() throws a NoSuchElementException if there is no value in the Optional (its value is null), you could have used Optional#orElse() like in:

return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null));

using Optional#isPresent(), as other answer are suggesting, is a (probably better) option.

For reference, check the documentation of orElse.


Note 2: also check this question and its answers: Why should Java 8's Optional not be used in arguments

Upvotes: 3

lczapski
lczapski

Reputation: 4120

You can do it in two way. With passing Optional to getCars or without. With passing:

public List<Car> getCars(Optional<Long> dateSt) {
   if(dateSt.isPresent()){
       return carReposistory.retrieveRegisteredCars(dateSt.get());
   }
   return carReposistory.retrieveAllCars(); 
}

Without passing: you have to create two separated methods:

public List<Car> retrieveRegisteredCars(Long dateSt) {
   return carReposistory.retrieveRegisteredCars(dateSt);
}

public List<Car> retrieveAllCars() {
   return carReposistory.retrieveAllCars(); 
}

and use them in controller:

return ResponseEntity.ok(
  dateSt.map(carService::retrieveRegisteredCars)
  .orElseGet(() -> carService.retrieveAllCars())
);

UPDATE

Or just pass null

return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null)));

Upvotes: 2

Related Questions