JSON对象属性无法返回-“无法读取未定义的属性”

时间:2020-04-22 20:29:03

标签: javascript json reactjs api parsing

好的,所以我在React中构建了一个自定义API。当我打电话时,我要获取JSON数据,并使用JSON.Stringify将其存储到本地存储中:

localStorage.setItem('user', JSON.stringify(response.data))

稍后,我将这个项目调用到首页上,以便在用户使用以下方式登录后返回一些数据:

var user = JSON.parse([localStorage.getItem('user')])

这将返回对象:

{
"OrderId":0,
"IsLoggedIn":true,
"ModeOfSaleId":64,
"OriginalModeOfSaleId":64,
"SourceId":8580,
"LoginInfo":{"ConstituentId":190554,"OriginalConstituentId":190554,"UserId":"test@email.org","Status":"P","FailedAttempts":0,"LockedDate":null,"ElectronicAddress":"test@email.org"},
"CartInfo":{"PerformanceCount":0,"PackageCount":0,"ContributionCount":0,"MembershipCount":0,"UserDefinedFeeCount":0,"GiftCertificateCount":0,"PaymentCount":0,"FirstSeatAddedDateTime":null},
"BusinessFacing":false,
"IsGuest":false,
"CheckoutStatus":{"Status":"No Checkout","Date":null},
"HasLockedSeats":false,
"SeatsExpired":false
}

问题:

未嵌套的属性通常返回{user.OrderId}{user.ModeOfSaleId},但是,尝试返回诸如{user.LoginInfo.ConstituentID}之类的嵌套值会导致错误:

Uncaught TypeError: Cannot read property 'ConstituentId' of undefined

返回{user.LoginInfo}实际上会返回一个对象,但是显然不能将其打印为字符串。返回{user.LoginInfo["ConstituentId"]}会导致错误:

Uncaught TypeError: Cannot read property 'ConstituentId' of undefined

是的,我很困惑,我不知道我怎么会错误地返回这个。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:0)

如何使用传播运算符获取所需的内容?

const user = JSON.parse(localStorage.getItem('user'))
const { ConstituentId, UserId } = user.LoginInfo

console.log(ConstituentId) // 190554

答案 1 :(得分:0)

此代码对我有用:

localStorage.setItem("user", JSON.stringify({
   "OrderId":0,
   "IsLoggedIn":true,
   "ModeOfSaleId":64,
   "OriginalModeOfSaleId":64,
   "SourceId":8580,
   "LoginInfo":{"ConstituentId":190554,"OriginalConstituentId":190554,"UserId":"test@email.org","Status":"P","FailedAttempts":0,"LockedDate":null,"ElectronicAddress":"test@email.org"},
   "CartInfo":{"PerformanceCount":0,"PackageCount":0,"ContributionCount":0,"MembershipCount":0,"UserDefinedFeeCount":0,"GiftCertificateCount":0,"PaymentCount":0,"FirstSeatAddedDateTime":null},
   "BusinessFacing":false,
   "IsGuest":false,
   "CheckoutStatus":{"Status":"No Checkout","Date":null},
   "HasLockedSeats":false,
   "SeatsExpired":false
}));

const user = JSON.parse(localStorage.getItem("user"));

console.log(user.LoginInfo.OriginalConstituentId);

答案 2 :(得分:0)

好吧,由于React处理Render事件的方式,所以我返回这些值的方式似乎是“问题”。当我在componentDidMount()事件上获取数据时,Render事件仍在此之前触发。

componentDidMount() {
  this.setState({ 
    user: JSON.parse([localStorage.getItem('user')]),
    users: { loading: true }
  });
}

因此在“渲染”事件中:

render() {
    const { user, users, loading } = this.state;
    var { ConstituentId, UserId } = user.LoginInfo


    return (
        <div className="col-md-6 col-md-offset-3">
            <h1>Hi!</h1>
            <p>{UserId}</p>
            <p>You're logged in with React & Basic HTTP Authentication!!</p>
            <h3>Users from secure api end point:</h3>
            <p>
                <Link to="/login">Logout</Link>
            </p>
        </div>
    );
}

一旦state.user设置componentDidMount()之前,它会触发两次。因此,由于未启用任何设置的第一个Render触发,因此我的代码出错了,因此出现了undefined消息。我想出了如何通过检查登录信息对象是否返回typeof object来绕开它。这是在我的渲染事件中:

var result = (typeof user.loginInfo === 'object');

if (result && loading) {
    console.log(result)
    console.log(user.LoginInfo.ConstituentId)
    var { ConstituentId, UserId } = user.LoginInfo
}

但这不是很优雅。因此,最终,我通过创建一个称为“正在加载”的状态道具,重新编写了在componentDidMount()中处理已卸载信息的方式:

this.state = {
  loading: true,
  user: {}
};

componentDidMount()中,我正在这样做:

this.setState({ 
  user: JSON.parse(localStorage.getItem('user')),
  loading: false
});

render()中:

const { loading, user } = this.state;
if (!loading) {
  var { ConstituentId, UserId } = user.LoginInfo
}
console.log(ConstituentId)

效果很好!

基本上,我只是通过在函数中将其设置为componentDidMount()来等待loading使用false状态触发。然后,我们知道它已加载并且可以成功呈现数据。