Scala - how to cast Option[X] to Option[y]

340 views Asked by At

I have simple service classes

trait ItemService[+A] {
  def getItem(id: Int): Option[A]
}
class MockItemService(implicit inj: Injector) extends ItemService[Item] with Injectable      {
  def getItem(id: Int) =  {
     Option(new Feature("My Headline",Author(2,"Barry White")))
  }
}

using scaldi im binding MockItemService to ItemService then accessing like

class Features(implicit inj: Injector) extends Controller with Injectable {
   val itemService = inject [ItemService[Item]]
   def item(cat:String, id:Int, urlTitle:String) = Action {   
      itemService.getItem(id).map { item => Ok(views.html.feature.item(item))      
   }.getOrElse(NotFound)    
  }  
}

what i want is for item to be of type Feature and not Item. Feature extends Item.

2

There are 2 answers

1
Rado Buransky On
    class Features(implicit inj: Injector) extends Controller with Injectable {
      val itemService = inject [ItemService[Item]]

      def item(cat:String, id:Int, urlTitle:String) = Action {
        itemService.getItem(id).map { item =>
           item match {
             case Feature(itsAFeature) => Ok(views.html.feature.item(itsAFeature))
             case itsAnItem => ???
           }
        }.getOrElse(NotFound)
      }
    }
1
AdiFatLady On

I found this worked

  itemService.getItem(id).map { item =>
       item match {
         case x: Feature => Ok(views.html.feature.item(x))
         case _: Any => NotFound
       }
    }.getOrElse(NotFound)

It still feels a bit clunky. I basically want getItem to return different types of objects that are all sub types of Item but at some point i will need to deal with the specific type of object. I could do getFeature etc but i may not know the type before i call getItem. If the controller doesnt need to know the specifics then surely its a good idea it doesnt.