Data not '.map'ing correctly

So, I am having a problem where 5 of my 6 variables are being transferred from one page to the next correctly, and I am honestly flabbergasted as to why the 6th isnt. Initially, this is where that data originally gets saved.

<Panel>
var UUID = require('UUIDModule');
var guid = UUID.getUUID();
var id = JSON.stringify(guid);

Context.createVehicle(id, vyear.value, vmake.value, vmodel.value, fuelType.value, comments.value);

Context Page ->

function createVehicle(id, vyear, vmake, vmodel, fuelType, comments) {
	console.log(id);
	var vehicle = {
		id: id,
		vyear: vyear,
		vmake: vmake,
		vmodel: vmodel,
		fuelType: fuelType,
		comments: comments,
	}

	var emailLong = FirebaseUser.email;
    var emailReady = emailLong.slice(0, -4);
    var emailShort = emailReady.split(".").join("");
    var url = encodeURI(rootURL + "users/" + emailShort + "/vehicles/" + id + ".json");

    fetch(url, {
        method: 'PUT',
        headers: { "Content-Type": "application/json"},
        body: JSON.stringify(vehicle)
    }).then(function(response) {
        console.log(JSON.stringify(response));
        return response.json();
    }).catch(function(err) {
        console.log("2 Error: " + err);
    });

	vehicles.add(vehicle);
}

</Panel>

That all works just fine. I pull the data back down later when someone goes to load their app, and it all displays correctly. So on my list, when someone selects a vehicle (that was previously saved from the above function) I run this function to transfer the data.

<Panel>

function goToVehicleInfo(arg) {
    var vehicle = arg.data;
    console.log(JSON.stringify(vehicle));
    router.push("vehicleInfo", vehicle);
}

</Panel>

Which works correctly, and in the console it displays this message:
{"vyear":"2014","vmake":"Mazda","vmodel":"3","fuelType":"","comments":"Red","id":"ceeea9d37e7645669141db9720d60d39"}

And on the following page, I .map it to separate that data and display it all in separate text boxes here.

<Panel>

var vehicle = this.Parameter;

Context.vyear = vehicle.map(function(x) { return x.vyear; });
Context.vmake = vehicle.map(function(x) { return x.vmake; });
Context.vmodel = vehicle.map(function(x) { return x.vmodel; });
Context.fuelType = vehicle.map(function(x) { return x.fuelType; });
Context.comments = vehicle.map(function(x) { return x.comments; });
Context.id = vehicle.map(function(x) { return x.id; });

Context page ->

var id = "";
var vyear = "";
var vmake = "";
var vmodel = "";
var fuelType = "";
var comments = "";

</Panel>

Every single one works, except for the line for the id. Which is problematic because I need that id in order to update that vehicles info in the database. Anyone know why?

Thanks in advance!

That’s some weird formatting. I suspect you actually don’t have JavaScript straight in Panel tags, do you?

Other than that, we’ll need to look at the actual project of yours or at a complete, minimal reproduction, because the snippets you posted do not tell the whole story.

What confuses me right away is the following. In your Context module, you have supposedly defined

var id = "";

which means that the id variable is just a static string. And then on the “following page” (whatever that means) you have

Context.id = vehicle.map(function(x) { return x.id; });

which sets the Context.id to an Observable, since that is what the .map function returns.

I don’t see any module.exports, or how you require() modules, and I don’t think you should be setting things on your Context from the “following page” in the first place.

I was just taking snippets from different pages, I have all the necessary requires and exports I believe. however, here is my github link to replicate it if you want.

The pages in question are the VehicleListPage and VehicleInfoPage, and the Context page is in the module folder.

And with that id being a static string, I’ve tried making it an observable from the get go, and it doesnt change anything. And all 5 other variables are static strings at the beginning as well, yet they all work fine.

Also, the <Panels were how I thought that you formatted here on the forum to look like blocks of code editor, didnt realize it was automatic.

There it is, the difference:

module.exports = {
    vyear: Context.vyear,
    vmake: Context.vmake,
    vmodel: Context.vmodel,
    fuelType: Context.fuelType,
    comments: Context.comments,

    cancel: cancel,
    save: save,
    goToSelections: goToSelections,
    info: info,

    viewLoaded: viewLoaded,
};

A derived Observable to get computed, it needs to be consumed. Your id does not have a subscription on it, so it never gets a value.

Yeah that worked, thanks. I didnt know that about Observables.

Just out of curiosity, I should be able to figure it out on my own but, when I edit information on that vehicle and resave, I know how to do PATCH for the json, but app side, how do I update/display the changes to that vehicle that I clicked?

Well if you have the id of the vehicle, and you have the list of all vehicle object in your Context, you could just implement a Context.updateVehicleInfo(id) method on it which iterates over the list, finds the right object and updates the information.

How do I identify the correct object though? In my head it would be something like

vehicles.map(function(x) … {} );

But how do I get the correct vehicle? Yes, the id is saved within the object, but thats in the larger array. Can I use .contain(id) or something?

You can just iterate over it and compare the id’s. When you have a match, you’ve found it.

So something like this?

for (x in vehicles.count) {
		var curVehicle = vehicles[x];
		if (curVehicle.id == id) {
			curVehicle.vyear = vyear;
			curVehicle.vmake = vmake;
			curVehicle.vmodel = vmodel;
			curVehicle.fuelType = fuelType;
			curVehicle.comments = comments;
			vehicles[x] = curVehicle;
		}
	}

I know a .map would accomplish the same but with less code, but I cant for the life of me remember .map syntax.

Wait no, that loop was not right, it should be like this

for (curVehicle in vehicles) {
		if (curVehicle.id == id) {
			curVehicle.vyear = vyear;
			curVehicle.vmake = vmake;
			curVehicle.vmodel = vmodel;
			curVehicle.fuelType = fuelType;
			curVehicle.comments = comments;
		}
	}

Yeah, something like that.

But if vehicles is an Observable, then .forEach.

Yup,

vehicles.forEach(function(x) {
		if (x.id == id) {
			x.vyear = vyear;
			x.vmake = vmake;
			x.vmodel = vmodel;
			x.fuelType = fuelType;
			x.comments = comments;
		}
	});

worked.

However, finally issue, I can track and see that that vehicle within the vehicles list is updated, but it wont show the change on the VehicleListPage list of vehicles. If i click on the updated vehicle, it shows the updated info, just not on the overarching list. The list populates directly from Context.vehicles, should it not update itself when on of those vehicles is modified?

Well, you have to iterate over Context.vehicles directly, not on a copy of that list. That should be it.

I am.

var vehicles = Observable(
);

function updateVehicle(id, vyear, vmake, vmodel, fuelType, comments) {
	var vehicle = {
		id: id,
		vyear: vyear,
		vmake: vmake,
		vmodel: vmodel,
		fuelType: fuelType,
		comments: comments,
	}

	var emailLong = FirebaseUser.email;
    var emailReady = emailLong.slice(0, -4);
    var emailShort = emailReady.split(".").join("");
    var url = encodeURI(rootURL + "users/" + emailShort + "/vehicles/" + id + ".json");

    fetch(url, {
        method: 'PATCH',
        headers: { "Content-Type": "application/json"},
        body: JSON.stringify(vehicle)
    }).then(function(response) {
        console.log(JSON.stringify(response));
        return response.json();
    }).catch(function(err) {
        console.log("2 Error: " + err);
	});

	vehicles.forEach(function(x) {
		if (x.id == id) {
			x.vyear = vyear;
			x.vmake = vmake;
			x.vmodel = vmodel;
			x.fuelType = fuelType;
			x.comments = comments;
		}
	});
}

Are both on the Context page, so it shouldnt be iterating over a copy, but rather the ‘vehicles’ from the top of the page.

I updated the github if you want to check the Context and VehicleListPage again.

As far as I can tell, that should just work.

This is perhaps the moment when we should return to you setting the individual page-local variables back to Context, which is completely unnecessary and likely causing some issues:

var vehicle = this.Parameter;

Context.vyear = vehicle.map(function(x) { return x.vyear; });
Context.vmake = vehicle.map(function(x) { return x.vmake; });
Context.vmodel = vehicle.map(function(x) { return x.vmodel; });
Context.fuelType = vehicle.map(function(x) { return x.fuelType; });
Context.comments = vehicle.map(function(x) { return x.comments; });
Context.id = vehicle.map(function(x) { return x.id; });
// ...
function save() {
    Context.updateVehicle(Context.id.value, Context.vyear.value, Context.vmake.value, 
    Context.vmodel.value, Context.fuelType.value, Context.comments.value);
    router.goBack();
}

Make those proper local variables and add some console.log()s all over the place to check what’s happening.

I am. Even when the list loads, I console.log(JSON.stringify(Context.vehicles), and it shows the updated information. I have no clue why the visible list doesnt update.

If you would add a .gitignore file to your repo and exclude the build and .uno folders, I could probably check it out some time during the day.

Delete those folders from the repository too, ain’t nobody wants to pull them! :slight_smile:

There I cleaned it up, sorry bout that haha. Just hadnt gotten around to it. Hopefully you can see whatever small detail that I am clearly missing.

Clearly, the project relies on having a working Firebase implementation and a particular user being authorised. There’s nothing I can do without those.

You should just keep debugging it yourself, and if all else fails, prepare a branch that one could simply check out and run on Fuse 1.6.1 without any additional hassle.