0

I have a function...

function createDatabase(data){  
    items = {};
    for (field in data){
        if (typeof data[field] == "object"){
            items.field = createDatabase(data[field]);
        } else {
            topic = data[field]
            items[field] = topic;
        }
    };
    return items;
}

And I call it with...

result = {"fields": createDatabase(jsonData)};
console.log(result);

My problem is that the result is only ever the final result of the recursive function calls. So the output is, for example...

{
  fields: {
    '0': 'Red',
    '1': 'White',
    '2': 'Blue'
  }
}

But red, white and blue don't appear until the end of a 3,000+ line file. What I'm aiming for is to get a sort of replicated version of the original JSON file, with embedded documents and all. I'll be doing something else obviously, but I'm trying to nail this iterative process first. It's like every time the code runs, it overwrites what was there before.

I'd like this line below to add on the results from another function call to an object:

items.field = createDatabase(data[field]);

EDIT

The start of my JSON file looks like this:

{
"Applied Sciences": {
    "Agriculture": {
        "Agricultural Economics": [
            "Agricultural Environment And Natural Resources",
            "Developmental Economics",
            "Food And Consumer Economics",
            "Production Economics And Farm Management"
            ],
        "Agronomy": [
            "Agroecology",
            "Biotechnology",
            "Plant Breeding",
            "Soil Conservation",
            "Soil Science",
            "Theoretical Modeling"
            ],

I am hoping to make the output of my code basically resemble this. Once I get this working, at each stage, I want to add some stuff to each item to build a database schema with, but I can't get past this first part. All I end up with is the final array of the final object at the bottom of the file. I have changed ".field" to "[field]" in the function, but this still doesn't help.

iamlc
  • 65
  • 5
  • it seems your function is expected to return a copy (limited to the own properties) of the given object. But you are setting `.field` in a way that it's overwritten every time the property you are iterating is an object and you are emptying items everytime anyway. Maybe if you also include the json data to better highlight your intentions. Anyway that seems like an attempt to copy an object recursively. There are better ways if you are interested – Diego D Jan 25 '23 at 08:02
  • You're right, ".field" isn't changing each time it iterates through data, like I thought it would. How could I do this, as I want to add a new field with a new name each time. https://stackoverflow.com/users/1221208/diego-d – iamlc Jan 25 '23 at 08:18
  • you wrote my entire profile url .. it was enough to cite my name like @iamlc. Anyway to better understand your problem... what are you trying to achieve exactly? you said now that you want to add a new field with a new name.. can you be more clear? you have an object to copy from.. how should be your output object? please edit your question being clear on your expectations about the input and output – Diego D Jan 25 '23 at 08:36
  • @DiegoD I have edited my post, hope that clarifies. I'm at the first stage of using this JSON to build a database with. – iamlc Jan 25 '23 at 08:43

1 Answers1

2

The scope is the current context of execution in which values and expressions are "visible" or can be referenced. (https://developer.mozilla.org/en-US/docs/Glossary/Scope)

function createDatabase(data){  
    const items = {};
    for (field in data){
        if (typeof data[field] == "object"){
            items.field = createDatabase(data[field]);
            // Not sure if it should be items[field]
        } else {
            const topic = data[field]
            items[field] = topic; 
           // Can be written as items[field] = data[field]
        }
    };
    return items;
}

Difference

function createDatabase(data){  
    items = {}; // Resets globalThis variable - items
    for (field in data){
        if (typeof data[field] == "object"){
            items.field = createDatabase(data[field]);
            
        } else {
            topic = data[field] // Resets globalThis variable - topic
            items[field] = topic;
        }
    };
    return items;
}

The variable items isn't declared for the function scope because there is no modifier such as var, let or const. This defaults to the global object which is window. The statement items={} always executes as window.items={}.

Sadiq Salau
  • 119
  • 5
  • This helped, I think. Thank you. I now get an output like this: `{ fields: { 'Applied Sciences': { Agriculture: [Object], Business: [Object], Engineering: [Object], Ergonomics: [Object]` This is better, but I'd like to keep expanding on all the [Object]'s. This output only goes one level deep. Anything you can think of that might be causing this? – iamlc Jan 25 '23 at 09:01
  • 1
    @iamlc You will need to convert the result to a JSON string using `JSON.stringify(result)`. The browser console expand objects as you click on them. – Sadiq Salau Jan 25 '23 at 09:04
  • Why am I doing that exactly? All the types seem to always be an 'object', which is what the function takes initially. – iamlc Jan 25 '23 at 09:09
  • @iamlc Based on your function, you will get the same result as your input. There isn't any other statement working on the data in your function. – Sadiq Salau Jan 25 '23 at 09:16