Attribute values missing on entities added on the fly
Platform-Group opened this issue · comments
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Html is added but with missing attributes
If the current behavior is a bug, please provide the steps to reproduce.
let locations = [
{
latitude: "51.505867",
longitude: "-0.075123",
scale: [300, 300, 300],
name: "Tower Bridge"
},
{
latitude: "51.527631",
longitude: "-0.152144",
scale: [300, 300, 300],
name: "Queen Mary's Garden"
},
{
latitude: "51.556692",
longitude: "-0.279666",
scale: [300, 300, 300],
name: "Wembley Stadium"
}
]
for (let i = 0; i < locations.length; i++) {
let location = locations[i]
const entity = document.createElement("a-entity");
entity.setAttribute('gps-new-entity-place', `latitude: ${location.latitude}; longitude: ${location.longitude};`)
entity.setAttribute("scale", location.scale);
entity.setAttribute("look-at", "[gps-new-camera]")
const pin = document.createElement('a-entity')
pin.setAttribute('gltf-model', '/assets/map_pin/scene.gltf')
entity.appendChild(pin)
const text = document.createElement("a-text");
text.setAttribute("scale", {
x: 0.7,
y: 0.7,
z: 0.7,
});
text.setAttribute("position", {
x: 0,
y: 0.6,
z: 0,
});
text.setAttribute("value", location.name);
text.setAttribute("align", "center");
entity.appendChild(text);
document.querySelector('#location-grouping').appendChild(entity)
}
Results in:
<a-entity gps-new-entity-place="" scale="" look-at=""><a-entity gltf-model=""></a-entity><a-text scale="" position="" value="Tower Bridge" align="center" text=""></a-text></a-entity>
<a-entity gps-new-entity-place="" scale="" look-at=""><a-entity gltf-model=""></a-entity><a-text scale="" position="" value="Queen Mary's Garden" align="center" text=""></a-text></a-entity>
<a-entity gps-new-entity-place="" scale="" look-at=""><a-entity gltf-model=""></a-entity><a-text scale="" position="" value="Wembley Stadium" align="center" text=""></a-text></a-entity>
As you can see, most of the attributes have missing values. I've attempted timeouts, doing this from AFRAME component inits or schemaUpdates, from window.onLoad.
What's weird though is I know that in some cases you can add new entities on the fly, for example:
let testEntityAdded = false;
const entity = document.createElement("a-triangle");
entity.setAttribute("scale", {
x: 20,
y: 20,
z: 20,
});
entity.setAttribute("material", { color: "red" });
const text = document.createElement("a-text");
text.setAttribute("scale", {
x: 4,
y: 4,
z: 4,
});
text.setAttribute("position", {
x: 0,
y: 1,
z: 0,
});
text.setAttribute("value", "N");
text.setAttribute("align", "center");
entity.appendChild(text);
document
.querySelector("#camera")
.addEventListener("gps-camera-update-position", (e) => {
console.log("gps position updated", e.detail.position);
entity.setAttribute("gps-new-entity-place", {
latitude: e.detail.position.latitude + 0.001,
longitude: e.detail.position.longitude,
});
if (!testEntityAdded) {
// Add a triangle to the north of the initial GPS position
document.querySelector("a-scene").appendChild(entity);
}
testEntityAdded = true;
});
Which seems to work fine, however I can't for the life of me figure out what the difference is. Aframe docs seem to indicate that there shouldn't be any issues with adding entities with javascript on the fly, so I'm not sure what's going wrong here. I can only assume it's an issue with how ar.js initalises.
What is the expected behavior?
Entities are created without missing attributes
Also it seems like this has been an issue for over three years: https://stackoverflow.com/questions/62903240/setattribute-does-not-set-value
I'm not sure to be honest, but does the data
of the gps-new-entity-place
initialise properly?
In any case you can always initialise using the method shown in the second example, by passing in objects containing the attributes you want to set.
sorry for the naiv suggestion
aren't you missing a ; after let location = locations[i]
did you check console and add some console.log in your code to check if you have the right values/variables/scopes?
Doesn't seem to make a difference if I change the setAttribute of gps-new-entity-place to an object:
entity.setAttribute('gps-new-entity-place', {
latitude: location.latitude,
longitude: location.longitude
})
<a-entity gps-new-entity-place="" scale="" look-at=""><a-entity gltf-model=""></a-entity><a-text scale="" position="" value="Tower Bridge" align="center" text=""></a-text></a-entity>
It does seem like gps-new-entity-place init() and update() are both getting latitude and longitude correctly somehow though. I added console logs and they come out fine:
gps-new-entity-place.js:17 init new {latitude: 51.556692, longitude: -0.279666}
gps-new-entity-place.js:36 update new {latitude: 51.556692, longitude: -0.279666}
x3
Odd that the attributes shown on the elements aren't correct and that they don't appear then.
@herrpedro you don't need semicolons in js, you can see most are missing in my code, I normally don't bother with them but I'm currently copying bits in and out all over and I'm not bothering to lint too much and some are left in from copied example code.
And yes I checked the variables are all correct at various points, I also checked to see if it makes a difference as to whether or not I use strings vs floats for lat and long but it seems to be broken either way.
I do invite you and @nickw1 to give the code a try yourself, or if you have example code of something like this I'd love to see if I can figure out where I'm going wrong. I'm guessing there's a particular broken component or something that's caused the example to work and my code to not work.
@Platform-Group i'm still in the part of writing code that works in all browsers. So far only firefox in android works ok. all the others need "simulated" coordinates to show the boxes in the right coordinates so i opened a bug of my own.. may be you can read it too and say something.. the thing is that it's so simple code that I dont know why it does not work,
its #558
already interacting with clicks and js and already building an api so all comes from server-side according to some things
meanwhile i keep reading docs and examples and imagining uses
happens inside of this
the attributes disappear when adding this js (same with the -nft)
this is to the extent of my poor knowledge
now i'll look into mine :)
all the best
Doesn't seem to make a difference if I change the setAttribute of gps-new-entity-place to an object:
entity.setAttribute('gps-new-entity-place', { latitude: location.latitude, longitude: location.longitude })
<a-entity gps-new-entity-place="" scale="" look-at=""><a-entity gltf-model=""></a-entity><a-text scale="" position="" value="Tower Bridge" align="center" text=""></a-text></a-entity>
It does seem like gps-new-entity-place init() and update() are both getting latitude and longitude correctly somehow though. I added console logs and they come out fine:
gps-new-entity-place.js:17 init new {latitude: 51.556692, longitude: -0.279666} gps-new-entity-place.js:36 update new {latitude: 51.556692, longitude: -0.279666} x3
Odd that the attributes shown on the elements aren't correct and that they don't appear then.
Strange, I've used this method of setting attributes many times and it works, see the examples in the new-location-based
directory within aframe
in the repo, for example. Let me try your example. So the POIs don't appear at the expected place?
@herrpedro you don't need semicolons in js, you can see most are missing in my code, I normally don't bother with them but I'm currently copying bits in and out all over and I'm not bothering to lint too much and some are left in from copied example code.
And yes I checked the variables are all correct at various points, I also checked to see if it makes a difference as to whether or not I use strings vs floats for lat and long but it seems to be broken either way.
I do invite you and @nickw1 to give the code a try yourself, or if you have example code of something like this I'd love to see if I can figure out where I'm going wrong. I'm guessing there's a particular broken component or something that's caused the example to work and my code to not work.
See for example:
https://github.com/AR-js-org/AR.js/blob/master/aframe/examples/new-location-based/poi/index.js
This is very similar in concept, it's adding the POIs using JSON returned from a web API, by dynamically setting gps-new-entity-place
.
@Platform-Group I have got your code working, one issue was that the scale
needs to be a JS object with attributes for x
, y
and z
.
I had to make some changes as I don't have your pin asset, but this example works:
<!DOCTYPE html>
<html>
<head>
<title>AR.js A-Frame - Points of Interest Example</title>
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script type='text/javascript' src='../../../../three.js/build/ar-threex-location-only.js'></script>
<script type='text/javascript' src='../../../build/aframe-ar.js'></script>
<script type='text/javascript' src='index.js'></script>
</head>
<body>
<a-scene vr-mode-ui='enabled: false' arjs='sourceType: webcam; videoTexture: true; debugUIEnabled: false' renderer='antialias: true; alpha: true'>
<a-camera gps-new-camera='gpsMinDistance: 5; simulateLatitude: 51.505; simulateLongitude: -0.0751'></a-camera>
</a-scene>
</body>
</html>
JS:
window.onload = () => {
const scene = document.querySelector("a-scene");
let locations = [
{
latitude: "51.505867",
longitude: "-0.075123",
scale: { x: 20, y: 20, z: 20},
color: 'yellow',
name: "Tower Bridge"
},
{
latitude: "51.527631",
longitude: "-0.152144",
scale: { x: 20, y: 20, z: 20},
color: 'blue',
name: "Queen Marys Garden"
},
{
latitude: "51.556692",
longitude: "-0.279666",
scale: { x: 20, y: 20, z: 20},
color: 'green',
name: "Wembley Stadium"
}
];
for (let i = 0; i < locations.length; i++) {
let loc = locations[i]
const entity = document.createElement('a-entity');
entity.setAttribute('gps-new-entity-place',
`latitude: ${loc.latitude}; longitude: ${loc.longitude}`
);
entity.setAttribute("look-at", "[gps-new-camera]")
entity.setAttribute("scale", loc.scale);
const pin = document.createElement('a-box')
// pin.setAttribute("scale", { x: 100000, y: 100000, z: 100000 } );
// pin.setAttribute('gltf-model', '/assets/map_pin/scene.gltf')
entity.appendChild(pin)
pin.setAttribute("material", { color: loc.color });
const text = document.createElement("a-text");
text.setAttribute("scale", {
x: 0.7,
y: 0.7,
z: 0.7,
});
text.setAttribute("position", {
x: 0,
y: 0.6,
z: 0,
});
text.setAttribute("value", loc.name);
text.setAttribute("align", "center");
entity.appendChild(text);
// document.querySelector('#location-grouping').appendChild(entity)
scene.appendChild(entity);
}
};
This is assuming a local installation of AR.js, you will need to obviously change the AR.js location.
yep. it works
but once simulateLatitute and simulateLongitude are removed and latlon coordinates of "locations" are adjusted to your location.... stops working (only works in ffox)
yep. it works but once simulateLatitute and simulateLongitude are removed and latlon coordinates of "locations" are adjusted to your location.... stops working (only works in ffox)
Do you have code for this? Are the POIs definitely close enough to your real GPS position?
A good test is this example here:
https://github.com/AR-js-org/AR.js/tree/master/aframe/examples/new-location-based/
This adds entities close to your GPS position automatically, wherever you are.
Does this example work for you?
@herrpedro sorry, wrong path for the example:
Should be: (EDITED)
https://github.com/AR-js-org/AR.js/tree/master/aframe/examples/new-location-based/basic-js
It's available in the repo and can be tested by starting a server in the root directory of the repo and navigating to the example.
Thanks @nickw1 that works great, do you know any way to turn on some kind of debugging though so I get error messages in my console for things like the wrong input type? Seems mad that it just silently fails so often, I could be making mistakes constantly and not know about it.
@Platform-Group great! Not sure but this may be of interest:
https://aframe.io/docs/1.4.0/introduction/visual-inspector-and-dev-tools.html