简体   繁体   English

JavaScript 映射 API 响应

[英]JavaScript Mapping an API response

I have an object which is being creating in the Context Component of my React application.我有一个 object 正在我的 React 应用程序的上下文组件中创建。

It looks something like this:它看起来像这样:

constructor(props) {
    super(props);
    this.state = {
      roles: [
        { role_type : { display : Manager }},
        { role_type : { display : Accounting}},
        { role_type : { display : Developer }},
      ],
   },
}

I am then making an API call which returns an array of role_type objects.然后我进行 API 调用,该调用返回一个 role_type 对象数组。 The return looks like this:返回看起来像这样:

[
  {
    "uuid": "a49-a2a5-fcce",
    "link": "organizations/roletypes/a49-a2a5-fcce/",
    "code": "MANG",
    "display": "MANAGER",
    "description": "MANAGER"
  },
  {
    "uuid": "681fbe",
    "link": "organizations/roletypes/681fbe/",
    "code": "SUPSPEC",
    "display": "Support Specialist",
    "description": "Support Specialist"
  },
  {
    "uuid": "0331ddccf",
    "link": "organizations/roletypes/0331ddccf/",
    "code": "PROJMANG",
    "display": "Project Manager",
    "description": "Project Manager"
  },
]

If my API call is successful I want to update each of the role_type objects whose display matches a display of the API response.如果我的 API 调用成功,我想更新显示与 API 响应的显示匹配的每个角色类型对象。

I have a working solution:我有一个可行的解决方案:

updateRoleTypes = () => {
  for(roleType in this.state.roles) {
    for(responseType of APIresponse) {
      if(responseType.display === this.state.roles[roleType].role_type.display) {
         this.setState( this.state.roles[roleType] : responseType)
      }
    }
  }
}

My teammate asked me today if I can do this without the for loop.我的队友今天问我是否可以在没有 for 循环的情况下做到这一点。 I'm not really sure how to change my code to get rid of the for loop though:/我不确定如何更改我的代码以摆脱 for 循环:/

You can try this:你可以试试这个:

updateRoleTypes = () => {
  this.setState(prevState => {
    const names = prevState.roles.map(role => role.role_type.display.toLowerCase())
    const updated = APIresponse.filter(r => names.includes(r.display.toLowerCase()))
    return {      
      roles: [
        ...prevState.roles.filter(row => !APIresponse.find(responseRow => responseRow.display.toLowerCase() === row.role_type.display.toLowerCase())),
        ...updated,
      ],
    }
  })
}

You are able to modify the state ?您可以修改state吗? If this is the case you can modify the data type of the roles to be an object of objects (This could use the code of the role as the key of the object), instead an array of objects .This will help you to access and check each role with certain key .如果是这种情况,您可以将roles的数据类型修改object of objects (这可以使用角色的code作为对象的键),而不是array of objects这将帮助您访问和用特定的key检查每个角色。

This way you should be able to use run just one loop to check if the new role exists in your state and update it if is the case.这样,您应该能够只运行一个循环来检查新role是否存在于您的state中,如果是则更新它。

Code代码


const state = {
  roles: {
    "MANG": { role_type: { display: "Manager" } },
    "ACCT": { role_type: { display: "Accounting" } },
    "DEV": { role_type: { display: "Developer" } }
  }
};

const response = [
  {
    uuid: "a49-a2a5-fcce",
    link: "organizations/roletypes/a49-a2a5-fcce/",
    code: "MANG",
    display: "MANAGER",
    description: "MANAGER"
  },
  {
    uuid: "681fbe",
    link: "organizations/roletypes/681fbe/",
    code: "SUPSPEC",
    display: "Support Specialist",
    description: "Support Specialist"
  },
  {
    uuid: "0331ddccf",
    link: "organizations/roletypes/0331ddccf/",
    code: "PROJMANG",
    display: "Project Manager",
    description: "Project Manager"
  }
];

const updateRoleTypes = newRoles => {
  let _roles = state.roles;
  newRoles.forEach(nR => {
    if (_roles[nR.code]) {
      _roles[nR.code].role_type = nR;
    }
  });

  return _roles;
};

This will return your mutated state you just have to setState with the new value.这将返回您的突变state您只需setState使用新值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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