These are chat archives for ramda/ramda

12th
Jun 2018
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:23 UTC

hi everyone. I'm trying to get a few props from an object:

props(['fullName', 'mobileTelephoneNumber', 'homeTelephoneNumber', 'emailAddress'], someObj);

and I would like to use or function with mobileTelephoneNumber and homeTelephoneNumber. so basically in my end result, I just want to have one of them (whichever is set). if mobile number is null, then it should use home number

and I cant figure out how to do it ramda - way
Mike Lambert
@lax4mike
Jun 12 2018 14:25 UTC
what key would this value be in?
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:25 UTC
phoneNumber
let me paste the whole thing
Mike Lambert
@lax4mike
Jun 12 2018 14:26 UTC
i would break this problem out, use props for all other ones, then compose that with a function that will assoc("phoneNumber", ...) with the right value
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:28 UTC
const zipper = (title, value) => ({ title, value });

const makeDetailsTable = useWith(zipWith(zipper), [
  identity,
  props(['fullname', 'mobileTelephoneNumber', 'emailAddress']),
]);

makeDetailsTable(contact.headings, housingOfficer);

// where 
contact.headings = [ 'Full Name', 'Phone number', 'Email Address' ];

housingOfficer = {
  fullName: 'John Smith',
  mobileTelephoneNumber: 13892,
  homeTelephoneNumber: null,
  emailAddress: 'some@test.com',
};
Mike Lambert
@lax4mike
Jun 12 2018 14:28 UTC
you can probably use R.either in that R.assoc
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:30 UTC
so the very final result is going to be
[
    { title: 'Full Name', value: 'John Smith' },
    { title: 'Phone number', value: 13892 },
    ...
];
Mike Lambert
@lax4mike
Jun 12 2018 14:32 UTC
also, check out R.pick instead of R.props and R.zip
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:33 UTC
I was actually going down R.pick way, but since headings are separate, I though R.props would make more sense
I guess I could do something like
const zipper = (title, value) => ({ title, value });

const choosePhoneNumber = ({ mobileTelephoneNumber, homeTelephoneNumber, ...rest }) => ({
  ...rest,
  phoneNumber: mobileTelephoneNumber || homeTelephoneNumber,
});

const makeDetailsTable = useWith(zipWith(zipper), [
  values,
  pipe(
    pickAll(['fullname', 'mobileTelephoneNumber', 'homeTelephoneNumber', 'emailAddress']),
    choosePhoneNumber,
    values
  ),
]);
could be an overkill, dunno..
Mike Lambert
@lax4mike
Jun 12 2018 14:41 UTC
there's also applySpec
const makeDetailsTable = R.applySpec({
  fullName: R.prop("fullName"),
  emailAddress: R.prop("emailAddress"),
  phoneNumber: R.either(R.prop("mobileTelephoneNumber"), R.prop("homeTelephoneNumber"))
});
that seems simpler
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:43 UTC
oh nice! didn't know that function, thank you :)
that looks awesome
Mike Lambert
@lax4mike
Jun 12 2018 14:45 UTC
then you can compose that like this:
const makeDetailsTable = R.compose(
  R.map(R.zipObj(["title", "value"])),
  R.toPairs,
  R.applySpec({
    "Full Name": R.prop("fullName"),
    "Email Address": R.prop("emailAddress"),
    "Phone Number": R.either(R.prop("mobileTelephoneNumber"), R.prop("homeTelephoneNumber"))
  })
);
or using juxt:
const makeDetailsTable = R.compose(
  R.map(R.zipObj(["title", "value"])),
  R.zip(["FullName", "Email Address", "Phone Number"]),
  R.juxt([
    R.prop("fullName"),
    R.prop("emailAddress"),
    R.either(R.prop("mobileTelephoneNumber"), R.prop("homeTelephoneNumber"))
  ])
);
i think the applySpec one is cleaner
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:49 UTC
yeah I like applySpec more. is there a way to pass the keys as arguments somehow?
 "Full Name":
this bit basically
that needs to come from a different object
Mike Lambert
@lax4mike
Jun 12 2018 14:49 UTC
hmm, i'm not sure how you would match the keys with the operations
unless it's by order, in which case the juxt version would work
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:52 UTC
ok here's my current solution
const zipper = (title, value) => ({ title, value });

const getHousingOfficerDetails = applySpec({
  name: prop('fullname'),
  phoneNumber: either(prop('mobileTelephoneNumber'), prop('homeTelephoneNumber')),
  email: prop('emailAddress'),
});

const makeDetailsTable = useWith(zipWith(zipper), [
  values,
  compose(
    values,
    getHousingOfficerDetails
  ),
]);
makeDetailsTable(contact.headings, housingOfficer)
Mike Lambert
@lax4mike
Jun 12 2018 14:53 UTC
i'd probably use zipObj instead of userWith(zipWith(zipper)
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:54 UTC
and then toPairs + map?
to have them as objects with title, value pairs
ok I'll play around with your versions a bit more :) thank you
Mike Lambert
@lax4mike
Jun 12 2018 14:55 UTC
also, applySpec + values is the same as juxt
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:55 UTC
:+1:
Mike Lambert
@lax4mike
Jun 12 2018 14:56 UTC
const headings = ["FullName", "Email Address", "Phone Number"];

const makeDetailsTable = (headings, officer) => R.compose(
  R.map(R.zipObj(["title", "value"])),
  R.zip(headings),
  R.juxt([
    R.prop("fullName"),
    R.prop("emailAddress"),
    R.either(R.prop("mobileTelephoneNumber"), R.prop("homeTelephoneNumber"))
  ])
)(officer);
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 15:00 UTC
that's perfect :)
thank you so much for your help!
Mike Lambert
@lax4mike
Jun 12 2018 15:00 UTC
:thumbsup: