6

I am trying to convert a Record to a vanilla JS object

module MyModule where

data Author = Author { name :: String, interests :: Array String }

phil :: Author
phil = Author { name: "Phil", interests: ["Functional Programming", "JavaScript"] }

when I access the object from JS

MyModule.phil

it contains other properties that I am not interested in (value0)

{"value0":{"name":"Phil","interests":["Functional Programming","JavaScript"]}}

how do you marshal the Records from the Purescript world to JS?

Tim Fairbrother
  • 928
  • 2
  • 9
  • 20
  • did you try: `JSON.stringify(MyModule.phil["value0"])` or `JSON.parse(JSON.stringify(MyModule.phil))["value0"]` ? – Santiago Hernández Aug 09 '16 at 05:32
  • that would work but that is not what I am asking here. There must be a way in Purescript to convert Records to js objects. I'm guessing it is in the purescript-argonaut or purescript-foreign packages but only see refs to JSON decoding and not js object literals. – Tim Fairbrother Aug 09 '16 at 05:41
  • 3
    Try using `newtype` instead of `data`. – Phil Freeman Aug 09 '16 at 05:47
  • don't newtypes only take one arg? How do you model complex records that need to be accessed from js? – Tim Fairbrother Aug 09 '16 at 05:55
  • ps. I was just working through the AddressBook example in your book and was trying to see if I could mix JS and Purescript. Are you saying that data Records or Data.Lists can't be accessed in a sane way from JS? – Tim Fairbrother Aug 09 '16 at 06:00
  • Sorry, I just tried using records for newtype and it worked. Thanks @PhilFreeman – Tim Fairbrother Aug 09 '16 at 06:07
  • 1
    Records are first class values in purescript, so a `newtype` works here because the record may have many fields, but is still one value. – gb. Aug 09 '16 at 10:22

1 Answers1

8

In section 10.16 of Purescript By Example, Phil Freeman shows an example of a newtype wrapping a record:

newtype FormData = FormData 
   { firstName :: String
   , lastName  :: String
   , street    :: String
   , city      :: String
   , state     :: String
   , homePhone :: String
   , cellPhone :: String 
   }

Then in section 10.18, he writes:

"The FormData type is a newtype for a record, so a value of type FormData passed to JSON.stringify will be serialized as a JSON object. This is because newtypes have the same runtime representation as their underlying data."

I think you need to peek under the hood and look at what psc generates to really appreciate this. We'll swap data for newtype,

newtype Author = Author { name :: String, interests :: Array String }

phil :: Author
phil = Author { name: "Phil", interests: ["Functional Programming", "JavaScript"] }

and this compiles to

// Generated by psc version 0.9.2
"use strict";
var Author = function (x) {
    return x;
};
var phil = {
    name: "Phil",
    interests: [ "Functional Programming", "JavaScript" ]
};
module.exports = {
    Author: Author,
    phil: phil
};
Stefan Ollinger
  • 1,577
  • 9
  • 16
liminalisht
  • 1,243
  • 9
  • 11