These are chat archives for ramda/ramda

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

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
what key would this value be in?
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:25
phoneNumber
let me paste the whole thing
Mike Lambert
@lax4mike
Jun 12 2018 14:26
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
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
you can probably use R.either in that R.assoc
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:30
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
also, check out R.pick instead of R.props and R.zip
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:33
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
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
oh nice! didn't know that function, thank you :)
that looks awesome
Mike Lambert
@lax4mike
Jun 12 2018 14:45
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
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
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
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
i'd probably use zipObj instead of userWith(zipWith(zipper)
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:54
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
also, applySpec + values is the same as juxt
geganizharadzeatamido
@geganizharadzeatamido
Jun 12 2018 14:55
:+1:
Mike Lambert
@lax4mike
Jun 12 2018 14:56
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
that's perfect :)
thank you so much for your help!
Mike Lambert
@lax4mike
Jun 12 2018 15:00
:thumbsup: