user1
user1

Reputation: 586

Typescript - Retrieve an object inside another object

I want to retrieve the object "rename_fields" from the main_object collect to use its field values:

export interface StdMap<T = string> {
    [key: string]: T;
}

export type StdFileBasedPluginHandlerConfiguration<
    SourceType extends StdMap<string | number>
> = {
    type: "std_file";
    data_files: string[];
    exclude_fields: string[];
    value_fields: string[];
    rename_fields: StdMap<StdMap<string>>;
    descriptor: string;
};

export type PluginHandlerConfiguration =
    | StdFileBasedPluginHandlerConfiguration<any>
    | { type: "not_required_configuration" }
    | undefined;

// export type PluginHandlerConfiguration = StdFileBasedPluginHandlerConfiguration<
//     any
// >;


export interface CollectorConfiguration {
    lastUpdate: Date;
    hashFile: string;
    code: string;
    plugin_path?: string;
    plugin_configuration: PluginHandlerConfiguration;
    related_codes?: string[];
    collections: { original: string; names: string[] };
    skipCollectData?: boolean;
    skipFlatGeneration?: boolean;
    extra_grouping_fields: string[];
    has_origins: boolean;
    force?: boolean;
    notify?: boolean;
    origins_that_generate_extra_records?: string[];
}

const main_object: CollectorConfiguration=
{ 
    "code" : "my_code", 
    "lastUpdate" : new Date("2020-01-28T00:00:00.000+0000"), 
    "collections" : {
        "original" : "collection", 
        "names" : [
            "collection_1",
            "collection_2"
        ]
    }, 
    "hashFile" : "ffc0b10ac2e7cd681f5666a474063165f5507212c45abf4ee2f85482ea866985,13c1dd232e13bc6d20ffe6213f38c5152e1f5e7f72366b461602d3cd876ef40f", 
    "extra_grouping_fields" : [
        "type"
    ], 
    "has_origins" : true, 
    "plugin_path" : "file/path_to_plugin", 
    "plugin_configuration" : {
        "type" : "std_file", 
        "data_files" : [
            "../file1.csv", 
            "../file2.csv"
        ], 
        "value_fields" : [
            "value1", 
            "value2"
        ], 
        "descriptor" : "type", 
        "exclude_fields" : [
            "excl1", 
            "excl2"
        ], 
        "rename_fields" : {
            "flat" : {
                "TEST1" : "test1", 
                "TEST2" : "test2", 
                
            }
        }
    }
}

    


Object.keys(main_object).forEach((key: Date | string | StdFileBasedPluginHandlerConfiguration<any> | boolean)=>{
    console.log(`KEY: ${key} - typeof key: ${typeof key}`);
    Object.keys(main_object).forEach((keyConfiguration) => {
        console.log(`DEBUG-->configuration keys: ${keyConfiguration}`);
        if (keyConfiguration === "plugin_configuration") {
            Object.keys(main_object[keyConfiguration]!).forEach(
                (keyPluginConfiguration: any) => {
                    console.log(
                        `DEBUG-->plugin_configuration - ${keyPluginConfiguration} --- END plugin_configuration`
                    );
                    if (keyPluginConfiguration === "rename_fields") {
                        Object.keys(
                            keyConfiguration![keyPluginConfiguration]!
                        ).forEach((keyRenameFields: any) => {
                            console.log(
                                `DEBUG-->rename_fields - ${keyRenameFields} --- END rename_fields`
                            );
                        });
                    }
                }
            );
        }
    });
});


but I've got the error:

test_object_loop.js:50
Object.keys(keyConfiguration[keyPluginConfiguration]).forEach(function (keyRenameFields) { ^
TypeError: Cannot convert undefined or null to object
at Function.keys ()
at test_object_loop.js:50:28
at Array.forEach ()
at test_object_loop.js:47:56
at Array.forEach ()
at test_object_loop.js:44:30
at Array.forEach ()
at Object. (test_object_loop.js:42:26)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)

How can I retrieve an object inside another object that has a particular type?

Upvotes: 1

Views: 645

Answers (1)

MaySoMusician
MaySoMusician

Reputation: 98

I don't know why you use so nested loops, but in order just to get the value of rename_fields, follow these steps:

  1. Ultimately you can access the value via main_object.plugin_configuration.rename_fields
  2. Because the type of plugin_configuration is defined as PluginHandlerConfiguration however...
    • plugin_configuration may be { type: "not_required_configuration" }
      • If so, you can't access its rename_fields because it doesn't have such a field
    • plugin_configuration may be undefined
      • If so, you can't even access its type field

So the theoretical code would be like this:

// Make sure `plugin_configuration` is not undefined
if (main_object.plugin_configuration) {
  // Make sure `plugin_configuration` has `rename_fields` field
  // by checking `type` field is "std_file"
  if (main_object.plugin_configuration.type === "std_file") {
    // Now you can safely access `rename_fields`
    const renameFields = main_object.plugin_configuration.rename_fields
  }
}

And these 2 if condition can be combined, as in the simpler, practical code below:

if (main_object.plugin_configuration && main_object.plugin_configuration.type === "std_file") {
  const renameFields = main_object.plugin_configuration.rename_fields
}

Upvotes: 1

Related Questions