0

I am trying to hit an API and retreive JSON. I am trying to iterate on records and trying to fetch results. The problem is that below are the warnings which are being populated as errors. I don't want to make them as warnings, but to find out what may be the solution to match may not be exclusive error message.

    case class Results(network: String,entity: String)
    val jsonStr=parse(content)
    val results = for {
               JArray(results) <- jsonStr
               JObject(result) <- results
               JField("network",JString(network)) <- result
               JField("entityId",JString(entityId)) <- result
             } yield Results(network,entityId)

Output:

[error] /home/jenkins/builds/workspace/ProjectName/core/src/main/scala/Settlement_Feed.scala:42: match may not be exhaustive.
[error] It would fail on the following inputs: JArray(_), JBool(_), JDouble(_),  JField(_, _), JInt(_), JNothing, JNull, JString(_)
[error]                     JObject(result) <- results
[error]                                     ^
[error] /home/jenkins/builds/workspace/ProjectName/core/src/main/scala/Settlement_Feed.scala:41: match may not be exhaustive.
[error] It would fail on the following inputs: JBool(_), JDouble(_), JField(_, _), JInt(_), JNothing, JNull, JObject(_), JString(_)
[error]                     JArray(results) <- jsonStr
[error]                                     
[error] two errors found

I have tried reading liftjson and scala docs for this, but couldn't find much of valuable information to resolve the error. I have tried keeping if loop and try to check instance of jsonstr, but it didn't work. Any suggestions is highly appreciated. Thanks a lot.

safian syed
  • 147
  • 1
  • 6

1 Answers1

0

You can't use pattern matching inside for comprehension in this case, because it only allows you to match one pattern. Instead convert to flatMap:

jsonStr match {
  case JArray(results) =>
    results.flatMap {
      case JObject(result) =>
        val networkOpt = result.collectFirst {
          case JField("network", JString(network)) => network
        }
        val entityIdOpt = result.collectFirst {
          case JField("entityId", JString(entityId)) => entityId
        }
        (networkOpt, entityIdOpt) match {
          case (Some(network), Some(entityId)) => Some(network, entityId)
          case _ => ???
        }
      case _ => ???
    }
  case _ => ???
}

Note that you need to replace ???s by what you want to do in those cases (if there is no network or entityId field, if results contains a value which isn't an object, if jsonStr is not an array).

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487