Having trouble accessing a JSON object with Typescript in an Angular 2 project

Something strange is happening with my code.

I am working with a JSON object:

{"login":"admin","name":"Admin"}

And this is the relevant part of my code:

private _userData: User;
...
private getUserData() {
    this._userInfoService.getUserInfo()
        .subscribe(
            data => {
                this._userData = data.json(); // (using <User> data.json() changes nothing
            },
            err => alert(err)
        );
}

This is how I defined the User interface:

export interface User {
    login: string;
    name: string;
}

But when trying to display the data in HTML using Angular:

<p>{{ _userData.login }}</p>
<p>{{ _userData.name }}</p>

I encounter errors like:

Error: EXCEPTION: TypeError: l__userData21 is null in [{{ _userData.login }} in UserHomeComponent@8:7]

Even though console.log shows the correct object:

Object { login: "admin", name: "Admin" }

The strange thing is, when I slightly modify the code like this:

private _name: string;
private _login: string;
...
private getUserData() {
    this._userInfoService.getUserInfo()
        .subscribe(
            data => {
                this._name = (<User> data.json()).name;
                this._login = (<User> data.json()).login;
            },
            err => alert(err)
        );
}

and adjust the view accordingly:

<p>{{ _login }}</p>
<p>{{ _name }}</p>

Then everything works fine! I'm puzzled by this issue (tried casting to <User> but it didn't help.)

@Edit: I have another class where similar code works perfectly:

export interface LoginData {
    access_token: string;
    token_type: string;
    refresh_token: string;
    expires_in: number;
    scope: string;
}


private _loginData = <LoginData> JSON.parse(sessionStorage.getItem("loginData")); //tried this also with User, doesn't work

and in the view:

<p>access_token: {{ _loginData.access_token }}</p>
<p>token_type: {{ _loginData.token_type }}</p>
<p>refresh_token: {{ _loginData.refresh_token }}</p>
<p>expires_in: {{ _loginData.expires_in }}</p>

Answer №1

when the user data is received asynchronously, it may be undefined initially. angular will throw an error when trying to access undefined.login at that point.

You can handle this by using the elvis operator to indicate that userData could be undefined.

Try the following:

<p>{{ _userData?.login }}</p>
<p>{{ _userData?.name }}</p>

Alternatively, you can use a wrapping *ngIf directive.

By the way, this issue is related to Angular 2 and JavaScript rather than TypeScript. Please update your title accordingly.

Answer №2

Attempting to create a data binding specifically to _userData.login rather than just _userData may lead to some errors you should be aware of.

Firstly, there are two potential issues at play here:

First: - When your data arrives asynchronously, the value of _userData.login is undefined initially as it relies on _userData, which is also undefined and lacks a default null value. This results in a failed data binding process, meaning you won't receive any updates when making changes later on. - On the other hand, your second example where _name and _login already have values (such as an empty string) allows for a successful data binding execution.

Second: - Another possible error lies in binding object references versus object attributes. - The way change listeners are implemented can affect whether assigning a new object to obj1 triggers the listener compared to changing an attribute like obj1.attr1.

Most likely, the issue stems from the first scenario. To confirm this, consider initializing the User object with an empty object in the constructor...

Answer №3

Consider incorporating the following code snippet before the <p> tags:

<div *ngFor="let data of _userData;">

Followed by:

<p>{{data.name}} 
</p></div>

Alternatively,

<div *ngIf="user">
<p>{{_userData.name}}</p>

Answer №4

To ensure safe navigation, make use of the ? operator.

<div>{{ _data?.name }}</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring Nested Collections with KnockoutJs in an Asp.net MVC Environment

I have the following .net class: public class JobDetailsDTO { public string JobName { get; set; } public string CompanyName { get; set; } public String[] IndustryName; } I am trying to connect this to a Knockout JS model, but my nested collec ...

PapaParse is not properly recognizing the date format

Having trouble creating a chart using JSON data from papaparse, resulting in the following error: c3.js:2100 Failed to parse x '10-18-2018' to Date object I've tried adjusting the date format in the CSV file but haven't had any luck. I ...

Error: Unable to access null properties while attempting to address Readonly property error by implementing an interface

Here is the code snippet I am working with: interface State { backgroundColor: boolean; isLoading: boolean; errorOccured: boolean; acknowledgment: string; } export class GoodIntention extends React.Component<Props, State> { ... onCli ...

Firebase authentication link for email sign-in in Angularfire is invalid

Currently, I am utilizing the signInWithEmailLink wrapper from AngularFire for Firebase authentication. Despite providing a valid email address and return URL as arguments, an error is being thrown stating "Invalid email link!" without even initiating any ...

Ways to resolve the issue of circular dependencies

I have 3 essential services: auth.service.ts, account.service.ts, http.service.ts During the user signup process, it is necessary to create a new account. As a result, I imported account.service.ts into auth.service.ts. This is done because the data fr ...

Exploring Angular2's DOMContentLoaded Event and Lifecycle Hook

Currently, I am utilizing Angular 2 (TS) and in need of some assistance: constructor(public element:ElementRef){} ngOnInit(){ this.DOMready() } DOMready() { if (this.element) { let testPosition = this.elemen ...

Working towards ensuring my website is responsive

Hello, I am a CSS beginner currently working as an intern. My task is to make a website's CSS compatible with Internet Explorer, and then make it responsive and scalable. Essentially, the design should retain its appearance when the window size change ...

What is the best way to verify JSON using JSON.NET when the data types are not consistent?

One of the challenges I'm facing involves a web call that returns JSON data. This response can either be in the form of an array or an object. I specifically want to verify if the returned response is indeed an array. To achieve this, I am utilizin ...

What steps can I take to ensure that an image does not exceed the size of its parent tag?

Is there a way to ensure that items placed in a container do not exceed the boundaries of the container? I am trying to use my logo as the home button, but when I set the image height and width to 100%, it becomes larger than the nav bar. The CSS for the n ...

Organizing JSON keys based on their values using Typescript

In the context of a main JSON structure represented below, I am interested in creating two separate JSONs based on the ID and Hobby values. x = [ {id: "1", hobby: "videogames"}, {id: "1", hobby: "chess"}, {id: "2", hobby: "chess ...

Using .get methods with jQuery's .on

I need to retrieve the tag name of the element that is clicked inside an li when the user interacts with it. The li element gets dynamically added to the HTML code. I have implemented the following code, but unfortunately, it does not seem to be functionin ...

An improved method for fetching data from the server at regular intervals of x minutes

Is setInterval the best way to periodically check for updates in a database and update the UI accordingly, or are there better approaches that I should consider? I've read conflicting opinions on using setInterval for this purpose, with some sources ...

Implementing a Class on Page Refresh in Next JS

I am fairly new to using react and nextjs. How can I insert a script in a component to add a class when the page reloads? The code below doesn't seem to work because the page is not yet rendered when I try to add the class for the body tag. const Mode ...

The function chartobject-1.render() is returning an error message stating: "Unable to locate the specified container within the document. This issue is occurring in the

I've encountered an issue while trying to integrate FusionCharts into my Vue.js project. Every time I attempt to render the charts within my components, I consistently run into this error. Here's a snippet of one of the components: <template&g ...

How to pass a variable or value through the async await API in the Vue.js and Laravel integration?

I'm facing an issue with my API where I want to check if a given email exists in the database, but every time I run it and view the console log, it returns undefined. Can anyone here suggest a better code snippet or approach for this? I specifically w ...

Generating a sequential array of dates and times in Angular

Currently, I am working on implementing a feature that will allow users to see the available visit times between two dates they select, specifically from 8:00 to 17:00 every day. For instance: If a user selects 1 Sep to 4 Sep, the system should return [1. ...

Consecutive pair of JavaScript date picker functions

My issue involves setting up a java script calendar date picker. Here are my input fields and related java scripts: <input type="text" class="text date" maxlength="12" name="customerServiceAccountForm:fromDateInput" id="customerServiceAccountForm:from ...

Using Puppeteer to Retrieve a List of Items with Identical Selectors

Issue: I am currently working on developing an end-to-end regression test for an EmberJS solution using NodeJS/CucumberJS/Puppeteer. However, I have encountered a challenge that I need help with. Challenge: The problem lies in selecting (page.click) and ...

Fill various dropdowns with a list or array of values discreetly without displaying the populated values on the visible interface

I have an array with values 1,2,3,4. Using an add function, I am able to create multiple dropdowns. By default, the first dropdown always has a value of one when initially set up. When we press add and populate the second dropdown with values 2,3,4, tho ...

How can I simulate mouse position in a UIWebView?

Can the mouse position (x,y) for HTML-5 elements on a UIWebView be programmatically set using stringByExecutingJavascript in order to trigger hover, mouse over, and other interactions? ...