简体   繁体   中英

Angular 5 component global variable is undefined?

My question is Global variable is undefined when the ngOnIt , AfterViewInit method is called. I'm fetching data from json file which is in asset folder. I have successfully passed the data to gotodef() function with one parameter. And from that gotodef() function I'm returning the variable. What I need is I want to return the array which is in gotodef() function with satisfying the condition from the json file (I mean from subscribe method).

Following is my code,

export class DashboardComponent implements AfterViewInit {

 column_data : any;

 constructor(private router:Router,private http:Http) {
            this.http.get('http://localhost:4200/assets/world_bank.json')
             .subscribe(data => {
                      data = (<any>data)._body;
                      let obj: MyObj = JSON.parse(data);
                      let outage_columns = obj.Outage.Columns;
                      let default_columns = obj.Default.Columns; // default_column's value is 2 in this case.
                      if(outage_columns == '')
                      {
                          let column_data = default_columns;
                          this.gotodef(column_data);
                      }

              });
    }
}

Gotodef Function :-

gotodef(column_data:any)
{

    if(column_data === '2')
    {
        console.log('in if statement');

        let columndata_1 = [
                { text: 'Product Name 1',  datafield: 'ProductName', width: '20%' , hidden:true },
                { text: 'Quantity per Unit',  datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'},
                { text: 'Unit Price',  datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' },
                { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' },
                { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'}
            ];
        return columndata_1;
    }
}

Now, It's jqwidgets component's line I want use the return value from function here in this.column_data but I can return it's value but first time it's undefined.

columns: any[] = this.gotodef(this.column_data);

So, I'm confuse how to achieve this task. How to declare proper variable to do this task.

EDIT :-

Full code (With Jqwidgets code)

@ViewChild('myGrid') myGrid: jqxGridComponent;

Rowclick(event: any): void {
    var args = event.args;
    var selectedRowIndex = args.rowindex;
    // alert(selectedRowIndex);
    $('#right_panel').css('display','block');
    $('body').removeClass('aside-menu-hidden');
}
source: any =
{
    datatype: 'xml',
    datafields: [
        { name: 'ProductName', type: 'string'  },
        { name: 'QuantityPerUnit', type: 'int' },
        { name: 'UnitPrice', type: 'float' },
        { name: 'UnitsInStock', type: 'float' },
        { name: 'Discontinued', type: 'bool' }
    ],
    root: 'Products',
    record: 'Product',
    id: 'ProductID',
    url: '../../assets/product.xml'
};

dataAdapter: any = new jqx.dataAdapter(this.source);

cellsrenderer = (row: number, columnfield: string, value: string | number, defaulthtml: string, columnproperties: any, rowdata: any): string => {
    if (value < 20) {
        return `<span style='margin: 4px; float:${columnproperties.cellsalign}; color: #ff0000;'>${value}</span>`;
    }
    else {
        return `<span style='margin: 4px; float:${columnproperties.cellsalign}; color: #008000;'>${value}</span>`;
    }
};

gotodef(column_data:any)
{
    console.log(column_data);
    if(column_data === '1')
    {
        console.log('in if');
        let columndata_1 = [
                { text: 'Product Name 1',  datafield: 'ProductName', width: '20%' },
                { text: 'Quantity per Unit',  datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'},
                { text: 'Unit Price',  datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' },
                { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' },
                { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'}
            ];
        return columndata_1;
    }
    if(column_data === '2')
    {
        console.log('in second if');
        let columndata_1 = [
                { text: 'Product Name 1',  datafield: 'ProductName', width: '20%' , hidden:true },
                { text: 'Quantity per Unit',  datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'},
                { text: 'Unit Price',  datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' },
                { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' },
                { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'}
            ];


    }
}

columns: any[] = this.gotodef(this.column_data);

columngroups: any[] =
[
    { text: 'Product Details', align: 'center', name: 'ProductDetails' }
];

If I put condition like this it's working,

if(column_data === '2' || typeof column_data === 'undefined')
    {
        console.log('in second if');
        let columndata_1 = [
                { text: 'Product Name 1',  datafield: 'ProductName', width: '20%' , hidden:true },
                { text: 'Quantity per Unit',  datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'},
                { text: 'Unit Price',  datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' },
                { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' },
                { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'}
            ];


    }

So, from this check I have figure it out that first time it's undefined and then it's setting value.

EDIT-2 :-

Thank you @ChrisG. My question is confusing so I have tried to explain it.

What I need is I want to return the array which is in gotodef() function with satisfying the condition from the json file (I mean from subscribe method).

Jqwidget's code and gotodef() function is in same class. So, I can get json file's data from function's argument-1 like this, gotodef(argument-1) in subscriber method and I can pass it to gotodef() .

So, I can get column_data from function and column_data's value is '2' it may be 1,2 or 3 etc.

Now if column_data has 2 value then I have to change the array. Please see the below code.

if(column_data === '2')
    {
        console.log('in second if');
        let Column_data_which_I_havetoreturn = [
                { text: 'Product Name 1',  datafield: 'ProductName', width: '20%' , hidden:true },
                { text: 'Quantity per Unit',  datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'},
                { text: 'Unit Price',  datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' },
                { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' },
                { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'}
            ];

     return Column_data_which_I_havetoreturn;
    }

and Now I have to use this returned data to this syntax,

columns: any[] = this.gotodef(Column_data_which_I_havetoreturn);

So, For that I have declared the variable Column_data_which_I_havetoreturn aboe the class like this Column_data_which_I_havetoreturn : any . I'm getting Column_data_which_I_havetoreturn but it's first time undefined.

You can try this solution (I changed a few names):

 class DashboardComponent { columnDataIndex = 1 // initial value constructor() { this.columns = this.getColumnData(this.columnDataIndex) // initialize this.columns // ajax call here // in subscribe, do: setTimeout(() => { console.log("ajax call succeeded"); this.columnDataIndex = 2 this.columns = this.getColumnData(this.columnDataIndex) }, 500); } getColumnData(index) { var column_data = [ { text: 'Product Name 1', datafield: 'ProductName', width: '20%' }, { text: 'Quantity per Unit', datafield: 'QuantityPerUnit', cellsalign: 'right', align: 'right' , width: '20%'}, { text: 'Unit Price', datafield: 'UnitPrice', align: 'right', cellsalign: 'right', cellsformat: 'c2', width: '20%' }, { text: 'Units In Stock', datafield: 'UnitsInStock', cellsalign: 'right', cellsrenderer: this.cellsrenderer, width: '20%' }, { text: 'Discontinued', columntype: 'checkbox', datafield: 'Discontinued', align: 'center' , width: '20%'} ]; if (index == 2) column_data[0].hidden = "true"; return column_data; } columns : any } const DC = new DashboardComponent(); console.log("columns", DC.columns[0]); setTimeout(() => { console.log("columns", DC.columns[0]); }, 1000); 

The fields should speak for themselves, but the basic idea is that the AJAX call so far only changes the type of column data that's supposed to ultimately end up in .columns , so I added an initial value 1 , initialize .columns in the constructor, then update it after a successful (simulated) AJAX call.

你可以这样尝试

this.gotodef(this.column_data);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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