简体   繁体   中英

changing a nested property of an object

Model:

function model() {
    return {
        title: { 
            "content": undefined,
            "validation": {
                "type": "string",
                "required": true,
                "minLength": 1,
                "maxLength": 3,
                validationErrorMessage: "Your title must be a valid string between 1 and 35 characters"
            }
        },

        email: {
            content: undefined,
            validation: {
                type: "email",
                required: true,
                minLength: 1,
                maxLength: 60,
                validationErrorMessage: "Your email must be between 1 and 50 characters"
            }
        },


        link: {
            content: undefined,
            validation: {
                type: "url",
                required: true,
                minLength: 1,
                maxLength: 500,
                validationErrorMessage: "Your link name must be a valid email between 1 and 50 characters"
            }
        },

        description: {
            content: undefined
        }
    }
}

Ramda code:

 let test = R.map( x => console.log(x.validation), model)
 console.log(test)

log result which is correct:

{ type: 'string',
  required: true,
  minLength: 1,
  maxLength: 3,
  validationErrorMessage: 'Your title must be a valid string between 1 and 35 characters' }
{ type: 'email',
  required: true,
  minLength: 1,
  maxLength: 60,
  validationErrorMessage: 'Your email must be between 1 and 50 characters' }
{ type: 'url',
  required: true,
  minLength: 1,
  maxLength: 500,
  validationErrorMessage: 'Your link name must be a valid email between 1 and 50 characters' }
undefined
{ title: undefined,
  email: undefined,
  link: undefined,
  description: undefined }

then why does:

   let test = R.map( x => x.validation = "replacement test", model)
   console.log(test)

logs:

{ title: 'replacement test',
  email: 'replacement test',
  link: 'replacement test',
  description: 'replacement test' }

I would have expected x.validation content to be replaced, not the entire x value. I don't get that.

map , like pretty well all Ramda functions, is meant to be used in an immutable way. It returns a list containing the elements you've returned from your function. But you don't (intentionally) return anything from your function, just adjust the original values. Javascript is making a return out of your assignment expression, though, one of the nice features of ES6 arrow functions.

If you want to keep your object intact, but update the 'validation' property, this might do:

R.map(R.assoc('validation', 'replacement text'), model());

assoc makes a shallow clone of your object, overwriting the specified property with a given value.

So, let's go trough your replacer lambda.

x => x.validation = "replacement test"

You map x.validation = "replacement test" to x . If you do

x => 1

Then every value in that array becomes 1.

When you use map, it changes the original array. In this case, x becomes x.validation wich becomes "replacement test" .

Use a forEach in this case

R.foreach(x => x.validation = "replacement test");

You're applying something to each iteration, so the fact that you assign to x.validation is irrelevant.

What matters is what is returned each time and what happens to it. Essentially you are just returning the string and assigning it each time, hence the result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM