JSON Свойство объекта не подлежит возврату - «Не удается прочитать свойство неопределенного» - PullRequest
0 голосов
/ 22 апреля 2020

Хорошо, я создаю собственный API в React. Когда я звоню, я получаю 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
}

Проблема:

Un- вложенные свойства обычно возвращают {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 голосов
/ 22 апреля 2020

Этот код работает для меня:

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);

0 голосов
/ 23 апреля 2020

Хорошо, поэтому способ, которым я возвращаю эти значения, кажется "проблемой" из-за способа, которым React обрабатывает событие Render. Когда я извлекаю данные о событии componentDidMount(), событие Render по-прежнему срабатывает непосредственно перед этим.

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

Итак, в событии Render:

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(), создав опору состояния под названием «loading»:

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 в функции. Тогда мы знаем, что он загружен и может успешно обработать данные.

0 голосов
/ 22 апреля 2020

Как насчет использования оператора спреда, чтобы получить то, что вы хотите?

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

console.log(ConstituentId) // 190554
...