Morgan G
Morgan G

Reputation: 3109

Variables not holding json data in angular2

So it's a weird issue that I have not been able to trouble shoot, I imagine part of it has to do with me not knowing async calls in angular but here we go!

I am retrieving the json data I want, but my variables are not grabbing it and I am completely lost as to why.

Here is my edit_role.component

import {Component} from 'angular2/core';
import { CORE_DIRECTIVES } from 'angular2/common';
import {RoleService} from './../services/roles.services';
import {OnInit} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import {RouteParams, RouterLink} from 'angular2/router';


@Component({
  selector: 'edit_role',
  providers: [RoleService],
  directives: [CORE_DIRECTIVES],
  templateUrl: 'app/roles/edit_role.html'
})
export class RoleEdit implements OnInit{

    role: any;
    modules: any;
    new_modules: any;
    params: any;

    constructor(private _roleService: RoleService, params:RouteParams){
        this.params = params.get('id');
    };

    ngOnInit(){
        this.getEditRoles(this.params);
    };

    getEditRoles(id){
        this._roleService.getEditRoles(id).subscribe(role_edit =>
            //console.log(role_edit.data[0])
            {this.role = role_edit.data[0],
            this.modules = role_edit.modules[0],
            this.new_modules = role_edit.new_modules[0]}
        );
    };
}

my role.services is:

import {Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/Rx';

@Injectable()
export class RoleService {

    constructor(public http: Http) { 
    }

    getEditRoles(id){
        return this.http.get('http://localhost:3000/api/roles/edit/' +id)
            .map((response => response.json()))
    }
}

my edit_role.html template

<div class="page-data">
    <form method="post" action="api/roles/edit/{{role.ID}}" name="{{role.ID}}">

        <table cellpadding="11">
            <tr>
                <div class="label"> Role Name </div>
                    <input type="text" name="role_name" value={{role.ROLE_NAME}}>

                <div class="label"> Description</div>
                    <input type="text" name="description" value={{role.DESCRIPTION}}>

                <div class="label"> Active Record </div>
                <div *ngIf="role.ACTIVE_FLAG === 'Y'">
                    <input type="radio" name="active_flag" value="Y" checked> Active
                    <input type="radio" name="active_flag" value="N"> Inactive
                </div>
                <div *ngIf="role.ACTIVE_FLAG === 'N'">
                    <input type="radio" name="active_flag" value = "Y"> Active
                    <input type="radio" name="active_flag" value= "N" checked> Inactive
                </div>
            </tr>
        </table>
    </form>
</div>

This is the only html I am testing atm so it's not using modules/new_modules my error

Cannot read property 'ID' of undefined in [api/roles/edit/{{role.ID}} in RoleEdit@1:21]

My data

{
new_modules: [
  {
    MODULE_NAME: "user_roles"
  }
],
modules: [
  {
    ROLE_ID: 6,
    MODULE_NAME: "roles",
    INSERT_ALLOWED_FLAG: "Y",
    UPDATE_ALLOWED_FLAG: "N",
    DELETE_ALLOWED_FLAG: "N",
    QUERY_ONLY: "Y"
  },
  {
    ROLE_ID: 6,
    MODULE_NAME: "test_mod",
    INSERT_ALLOWED_FLAG: "Y",
    UPDATE_ALLOWED_FLAG: "N",
    DELETE_ALLOWED_FLAG: "N",
    QUERY_ONLY: "N"
  },
  {
    ROLE_ID: 6,
    MODULE_NAME: "users",
    INSERT_ALLOWED_FLAG: "Y",
    UPDATE_ALLOWED_FLAG: "Y",
    DELETE_ALLOWED_FLAG: "Y",
    QUERY_ONLY: "Y"
  }
],
data: [
  {
    ID: 6,
    ROLE_NAME: "Fire",
    DESCRIPTION: "Something hot",
    ACTIVE_FLAG: "Y"
  }
 ]
}

I know this error is caused by the fact that my roles, modules, and new_modules are not receiving any data. The weird part is, when I do console.log(role_edit.data[0]) it retrieves my json data.

So I have 2 problems I think, one is that my HTML loads before my request is received which crashes my html before load. The other part is, that even though I can console.log my data I can't actually store it in a variable.

Upvotes: 2

Views: 509

Answers (1)

SnareChops
SnareChops

Reputation: 13347

Angular 2 expects all bound properties to not be undefined. In your case role is undefined at first, and then gets loaded in after. Thankfully the Angular team has thought of this and has introduced a syntax that will help with this.

example:

{{role?.ID}}

This will prevent the error from occurring and will simply display nothing, until role is defined and then it will display the value of ID

Therefore this HTML should solve the issue you are having

<form method="post" action="api/roles/edit/{{role?.ID}}" name="{{role?.ID}}">
    <table cellpadding="11">
        <tr>
            <div class="label"> Role Name </div>
                <input type="text" name="role_name" value={{role?.ROLE_NAME}}>

            <div class="label"> Description</div>
                <input type="text" name="description" value={{role?.DESCRIPTION}}>

            <div class="label"> Active Record </div>
            <div *ngIf="role?.ACTIVE_FLAG === 'Y'">
                <input type="radio" name="active_flag" value="Y" checked> Active
                <input type="radio" name="active_flag" value="N"> Inactive
            </div>
            <div *ngIf="role?.ACTIVE_FLAG === 'N'">
                <input type="radio" name="active_flag" value = "Y"> Active
                <input type="radio" name="active_flag" value= "N" checked> Inactive
            </div>
        </tr>
    </table>
</form>

Upvotes: 1

Related Questions