question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot convert from Map[_, Any]

See original GitHub issue

While trying out the library, I have realized that there are no implicit conversions for Any or AnyVal.

For example, consider the following code:

case class Container(m: Map[String, AnyVal])
val container = Container(Map("name" -> "John".asInstanceOf[AnyVal], "age" -> 50))
container.asJson

This will not work because there is no implicit mapping for a AnyVal (or for Any, for that matter).

I’ve been trying to understand how one may write their own implicit conversion guidelines in such cases for converting from objects to JSON and vice versa.

The end goal here is something like being able to convert between any arbitrary JSON to a Map[String, Any], and vice versa.

Note: If such a functionality already exists, please point me to the right direction. I was not able to find this in the documentation or otherwise.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

17reactions
travisbrowncommented, May 15, 2016

@robsonpeixoto The Either constructors are case classes, so generic will produce instances for them just like any other case classes (there are no automatically-provided Either instances, and it’s not special-cased).

If you want an untagged representation, you can do something like this:

import io.circe._, io.circe.generic.auto._, io.circe.jawn._, io.circe.syntax._

implicit val encodeIntOrString: Encoder[Either[Int, String]] =
  Encoder.instance(_.fold(_.asJson, _.asJson))

implicit val decodeIntOrString: Decoder[Either[Int, String]] =
  Decoder[Int].map(Left(_)).or(Decoder[String].map(Right(_)))

And then:

scala> println(m1.asJson)
{
  "name" : "John",
  "age" : 50
}

scala> decode[Message](m1.asJson.noSpaces)
res1: cats.data.Xor[io.circe.Error,Message] = Right(Map(name -> Right(John), age -> Left(50)))

Does that work for you?

1reaction
travisbrowncommented, Mar 3, 2016

@ChetanBhasin circe is built on the idea of having types drive serialization—you ask for a JSON representation of a value of type Map[String, User], for example, and the appropriate encoders are selected at compile-time—there’s no cost or danger of reflection at runtime. circe is entirely helpless when it comes to Any or AnyVal, where you can’t do anything reasonable with a value except reflect on it at runtime (if that counts as reasonable).

This is by design, and has two goals: to keep the library simple and safe by avoiding any use of runtime reflection, and to promote the use of types. In many ways Map[String, Any] is the opposite of type-safe functional programming, and circe aims to make it both possible and desirable to avoid having types like Map[String, Any] show up anywhere in your program.

Of course you could write your own Encoder and Decoder instances for types like Map[String, Any], but they’d be unsafe, unidiomatic, and possibly less performant (because of the necessity of runtime reflection), so circe itself will almost definitely never provide anything like that off the shelf.

I’d recommend trying to avoid Map[String, Any] entirely, but if you’re stuck with it and you really want to use circe (as opposed to a JSON library that embraces runtime reflection, which is most of them 😄), you could try to cast and convert your Map[String, Any] values into something more type-full, like e.g. Map[String, Either[Int, String]], which circe will happily encode and decode.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot convert object to map of any single type - Terraform
I suppose because tomap of an empty object . I know that removing empty “b” object completely will avoid this error but for...
Read more >
Type mismatch: cannot convert from Map<Object,List ...
The following code does the same thing as your code but splits up the collect in to multiple map steps, this may work...
Read more >
cannot convert HashMap to class exception
I get the following exception when trying to deserialize a map java.lang.ClassCastException: Cannot convert class java.util.HashMap to class ...
Read more >
Type mismatch: cannot convert from Object to Map<String ...
This line gives me an error: private static final Map<String, IndexType> INDEX_TYPE_MAP = Arrays ...
Read more >
Type mismatch: cannot convert from element type Object to ...
Type mismatch: cannot convert from element type Object to Map. ... Any good reason to instantiate HashMap<Object, Object>?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found