Nested For loops and JSON

This is a question building off of an earlier issue. Basically, I’ve made my JSON a bit more complicated and trying to return values for prompts within the nested loops

Here’s the new JSON:

{
  "1": {
    "name": "Destroy the Death Star",
    "creation date": "2019-12-24",
    "priority": [
      {
        "name": "Get the plans to the Death Star",
        "creation date": "2019-12-26",
        "complete": false,
        "completion date": "",
        "morning": [
          {
            "date": "2019-12-27",
            "tasks": [
              {
                "name": "get transport",
                "complete": false
              },
              {
                "name": "find a pilot",
                "complete": false
              }
            ]
          },
          {
            "date": "2019-12-26",
            "tasks": [
              {
                "name": "find blaster",
                "complete": true
              },
              {
                "name": "find droids",
                "complete": true
              }
            ]
          }
        ],
        "night": [
          {
            "date": "2019-12-27",
            "description": "ready to leave this planet with a pilot",
            "enough": true
          },
          {
            "date": "2019-12-26",
            "description": "great day today gathering materials",
            "enough": true
          }
        ]
      },
      {
        "name": "Determine how to overthrow empire",
        "creation date": "2019-12-24",
        "complete": true,
        "completion date": "2019-12-25",
        "morning": [
          {
            "date": "2019-12-25",
            "tasks": [
              {
                "name": "Make alliances with aliens",
                "complete": true
              }
            ]
          }
        ],
        "night": [
          {
            "date": "2019-12-25",
            "description": "Made a great decision today to ally with squid people who had the idea to destroy the death star",
            "enough": true
          }
        ]
      }
    ]
  },
  "2": {
    "name": "Train to be a jedi",
    "creation date": "2019-12-24",
    "priority": [
      {
        "name": "Learn to use the force",
        "creation date": "2019-12-26",
        "complete": false,
        "completion date": "",
        "morning": [
          {
            "date": "2019-12-27",
            "tasks": [
              {
                "name": "get a lightsaber",
                "complete": false
              },
              {
                "name": "get training",
                "complete": false
              }
            ]
          },
          {
            "date": "2019-12-26",
            "tasks": [
              {
                "name": "find yoda",
                "complete": true
              },
              {
                "name": "eat food",
                "complete": true
              }
            ]
          }
        ],
        "night": [
          {
            "date": "2019-12-27",
            "description": "great time training today",
            "enough": true
          },
          {
            "date": "2019-12-26",
            "description": "found a master",
            "enough": true
          }
        ]
      },
      {
        "name": "Leave home",
        "creation date": "2019-12-24",
        "complete": true,
        "completion date": "2019-12-25",
        "morning": [
          {
            "date": "2019-12-25",
            "tasks": [
              {
                "name": "find a speeder craft",
                "complete": true
              }
            ]
          }
        ],
        "night": [
          {
            "date": "2019-12-25",
            "description": "Gonna leave this place",
            "enough": true
          }
        ]
      }
    ]
  }
}

Here’s my code which sort of works but returns confused results:

// Goals testing

// Get the JSON file

let fmCloud = FileManager.createCloud();
let file = fmCloud.readString("/Goals/goals-new.json");
let json = JSON.parse(file);

// // Prompt
/* --------------------- */

let today = Date.today().toString("dddd, MMM d");
let dStamp = Date.today().toString("yyyy-MM-dd");

//TODO: maybe move the prompt into the first "for" loop so that each goal gets its own prompt?

let p = Prompt.create();
p.title = "Goals Today";
var	tasks;
for (let goal in json)
{
	let goalName = json[goal].name;
	p.addLabel("gName",goalName,{"textSize":"headline"});


	let priority = json[goal].priority[0].name;
	
	p.addLabel("complete", "Intentions Completed Today?")
	for (let i in json[goal].priority[0].morning[0].tasks)
	{
		let taskToggle = json[goal].priority[0].morning[0].tasks[i].complete+"toggle";
		let taskLabel = json[goal].priority[0].morning[0].tasks[i].name;
		p.addSwitch(taskToggle,taskLabel);	
	}
		
	let toggle = goal + "toggle";
	let field = goal + "field";
	p.addLabel("pName", priority,{"textSize":"headline"});
	p.addSwitch(toggle, "Enough today?", false);
	p.addTextView(field, "Description", "", {height: "3"});
}

p.addButton("ok");

if (p.show())
{
	for (let goal in json)
	{
		for (let i in json[goal].priority[0].morning[0].tasks)
		{
			let taskToggle = json[goal].priority[0].morning[0].tasks[i].complete+"toggle";
			json[goal].priority[0].morning[0].tasks[i].complete = p.fieldValues[taskToggle];
		}
		let toggle = goal + "toggle";
		let field = goal + "field";

		json[goal].priority[0].night.unshift({"date":dStamp,"description":p.fieldValues[field],"enough":p.fieldValues[toggle]});
		
	}
	let output = JSON.stringify(json);
	let success = fmCloud.writeString("/Goals/goals4.json", output);
}
else
{
	context.cancel();
}

Everything in the Prompt itself works fine. Within the nested loops looking for “tasks”, I get the correct value for each of the four tasks in the JSON. Hurray!

However, the script isn’t writing the correct results from the prompt. If I mark one task “true”, every task gets a “true” value in the “complete” key, even if no other tasks are checked off in the prompt.

Just a quick read over this, but I think you are naming all your switches the same thing. See this line:

let taskToggle = json[goal].priority[0].morning[0].tasks[i].complete+"toggle";

The complete value is always true, so you are naming all your switches “truetoggle”.

I think you meant to use:

let taskToggle = json[goal].priority[0].morning[0].tasks[i].name+"toggle";

In both loops.

1 Like

that did it. thanks so much!!