Error when using addChild twice in one function in NativeScript - javascript

I am trying to dynamically create stackLayouts and add them to the existing scrollView but got an error:
JS ERROR TypeError: scrollView.addChild is not a function. (In 'scrollView.addChild(stackLayout)', 'scrollView.addChild' is undefined)
but by using console.log it sees both of them:
StackLayout(10) ScrollView<dates>#diary/diary-page.xml:4:7;
My code is:
input.forEach(function(entry) {
const scrollView = page.getViewById("dates");
var stackLayout = new StackLayout();
stackLayout.className = 'date';
var label = new Label();
label.text = entry.Date;
stackLayout.addChild(label);
console.log(stackLayout + ' ' + scrollView);
scrollView.addChild(stackLayout);
});
Can anybody help with this strange behaviour? Thank you

What's the code of your getViewById function? It looks like it doesn't return DOM element, this is why you can't call addChild on scrollView.

Found the reason here: How to nest elements in dynamically created ScrollView?
"ScrollView is actually an implantation of ContentView so the right way to set it's content is by doing:
scrollview.content = stacklayout
Note: Only can only set a single content view. That's the reason there is not addChild method as it suggests multiple children are supported."

Related

Why are remove() and removeChild() not working

Well I don't exactly understand if its the functions or the flow of my program. I'm querying a simple API for practice which fetches the longitude and latitude of ISS.I wanted to do it every second that's why I used setInterval(). Now I want that when the next data comes the current one automatically removes/disappear and the only the displays, that's why I tried using remove() and removeChild() both but its not removing the element and the new data keeps appearing one below the other. Here's the javascript:
const url = "https://api.wheretheiss.at/v1/satellites/25544";
const box = document.getElementById('div');
function setup(){
let request = new XMLHttpRequest();
request.onload = gotData;
request.open('GET',url);
request.send();
}
setInterval(setup,1000);
function gotData(){
data = JSON.parse(this.responseText);
const box_lat = document.createElement('H2');
const box_long = document.createElement('H2');
box_lat.innerText = "Latitude: " + data.latitude;
box_long.innerText = "Longitude: " + data.longitude;
document.body.appendChild(box);
if(box.hasChildNodes()){
box.removeChild(box_lat);
box.removeChild(box_long);
}else{
box.appendChild(box_lat);
box.appendChild(box_long);
}
}
This gives the following error:---
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
at XMLHttpRequest.gotData (http://127.0.0.1:3000/Projects/CSS_JS/JavaScript/iss.js:30:9)
I also tried using box.childNodes.length > 0 in the if condition but still got the same result.
Using document.body.removeChild(box) to remove the complete box item never shows that div element!
All I want is that data should update automatically without repeating!
box.removeChild(box_lat);
You are trying to remove box_lat from box.
const box_lat = document.createElement('H2');
but you just created box_lat a few lines before and haven't appended it anywhere.
It sounds like you are trying to access the box_lat variable from the previous invoke of the function … but that's a different variable with a different value and you don't have access to it here.
You need to find the elements you actually want to remove, e.g.:
box.querySelector("h2").remove()

I can't access my current element

This is an instance of Rappid Toolkit which uses jointJS for building visual tools as for web development. http://i.stack.imgur.com/6XSis.png
In this toolkit you can make a graph which can become a website.
My problem is the following one:
In every single element of this graph there is a box below it with:x,y,width,height,angle.
I want to change this information of this boxcontent and to display some info from this element but the code in which I have to add my snippet is the following(var Halo is the var for my element in the graph):
var halo = new joint.ui.Halo({
cellView: cellView,
boxContent: function(cellView) {
return"Here I want to display my box content info instead of x,y,width,height, angle";
}
}).render();
If I try to add my code inside it to access in JSON format my current element info my full code is:
var halo = new joint.ui.Halo({
cellView: cellView,
boxContent: function(cellView) {
// Drawing
var selectedObjectDataText = JSON.stringify(this.cellView.toJSON());
var selectedObjectDataJSON = JSON.parse(selectedObjectDataText);
return(selectedObjectDataJSON[0].wi_name);
}
}).render();
where wi_name is the name of my element but in the first line I can't access the specific element of my graph.
var selectedObjectDataText = JSON.stringify(this.cellView.toJSON());
Is there any global way to access my halo(my graph element) since this.cellView.toJSON() doesn't work?
I tried this.model.toJSON() this.cellView.model.toJSON() etc with no result
Note that JointJS links and elements are Backbone Models (linkView and elementView are Backbone Views).
To get the current value of an attribute use get() method.
boxContent: function(cellView) {
return cellView.model.get('wi_name');
}
Alternatively you can use prop(), that can return also nested properties of a model.
boxContent: function(cellView) {
return cellView.model.prop('wi_name');
}
It worked for var selectedObjectDataText = JSON.stringify(cellView.model.toJSON());
Thank you all for your support.

ngjstree: error when select node automatically

I'm using NgJsTree (https://github.com/ezraroi/ngJsTree) for create a tree. I would like that the option choose by user was saved; so I'm saving the user's choice and the full path in a pair of variable. In particular case, I get the full path like this data.instance.get_path(data.node,'/'); and the selected node in this way data.instance.get_node(data.selected[i])
I trigger the loaded event with this function:
openSelectedNode = function(e, data){
var nodes = config.path.split("/");
for(var i=0;i<nodes.length;i++){
$(this).jstree("open_node", $('#' + nodes[i].replace(" ", "")));
}
$(this).jstree('select_node', $('#' + nodes[nodes.length-1] ));
}
So in this way, when the tree is load, I can reopen the tree and select the correct node. The code works, but in console I have this error:
Uncaught TypeError: Cannot read property 'parents' of undefined
It isn't the right approach? Am i doing any errors?
Thanks in advance.
Regards
It looks like you might be calling node.parents somewhere, which happened to me. Also, I would approach your problem different.
I would:
Use the instance provided by ngJStree to reference the tree, and then use
var selectedNode = vm.treeInstance.jstree(true).get_selected();
Store that nodes id, then set its state to "selected: true" before you create the the tree the next time. It should be already selected that way.

Display neo4j node properties with Sigma.js

I am using Sigma.js with the cypher plugin to visualise my neo4j database. After following the simple example here https://github.com/jacomyal/sigma.js/blob/master/examples/load-neo4j-cypher-query.html , it is working well. I edited the plugin so that the graph labels displayed are the names of my neo4j nodes, however I would also like to show the other node properties when clicking on the label or node.I am quite new to JavaScript so would like to know if this is possible for a beginner like me to do and if it is where is the best place for me to start.
You have to register an event on the click or hover node.
There is an example into sigmajs for event : https://github.com/jacomyal/sigma.js/blob/master/examples/events.html
This is a short code that demonstrate how to make this. Replace the alert method by what you want.
sigma.bind('overNode', function(event) {
alert(event.data.node);
});
If you just want to discover your database, take a look at tank-browser : https://www.npmjs.com/package/tank-browser
Cheers
You have to edit Cypher plugin
First: Define var let's assume we will call it "has" at the beginning of the file.
Second: You should add ul in your html and add class to it called 'popover'
Third: Add to cypherCallback method you should add inside else if (typeof sig === 'object')
sig.graph.read(graph);
sig.bind('clickNode', function(e) {
var clicknode = e.data.node;
// empty the printed list
$('.popover').empty();
has='';
// create the tlis tof prop. from returend Object
for(var keys in clicknode.neo4j_data ){
$('.popover').append(' <li>' + keys + ' = '+ clicknode.neo4j_data[keys] + '</li>');
has+= 'n.' +keys + '="'+ clicknode.neo4j_data[keys] + '"AND ';
}
$('.popover').show();
});
sig.bind('clickStage', function(e) {
$('.popover').hide();
});

Why does onclick's handling function not work as expected?

I have the following little piece of code:
var instance = this;
window.onload = function () {
for (var i = 0; i < array.length; ++i) {
var currentDivId= array[i];
var currentDiv = document.getElementById(currentDivId);
try {
if (!currentDiv) {
throw 'Div id not found: ' + currentDivId;
}
var image = document.createElement('img');
image.src = 'img.jpg';
image.onclick = function() {
instance.doSomething(currentDivId);
};
currentDiv.appendChild(image);
}
catch(e) {
console.warn('oops');
}
}
};
This code is passed an array of id of divs. What it does is that, it renders an image at each of those divs and set their onclick property.
Say I have an array of strings: ['abc', 'xyz']
I want the code to place an image inside <div id="abc"></div> and another image inside <div id="xyz"></div>.
When you click the first image, instance.doSomething function should be called with parameter 'abc' and vice versa.
But the code does not work as expected. It always calls instance.doSomething with the last parameter in the array, in this case, 'xyz'.
I'm new to JS and still don't have a solid grasp of its inner workings. What's wrong here and how can I fix it?
Any help appreciated.
image.onclick = function() {
instance.doSomething(this.parentNode.id);
};
That should do it. Since we know that the image is inside the div we want to get at, just go one dom element up and get its id.
Welcome to the wonderful world of Javascript scoping issues. As it stands now, JS is treating your onclick code as something like "when this object is clicked, fetch the value stored in the currentDivID variable AT THE TIME THE CLICK occurs and pass it to the doSomething function".
What you should do is base the argument on the image object itself. Every DOM object knows where it is in the DOM tree, so at the time it's clicked, the onclick code should use DOM traversal operations to figure out which div it's inside of and dynamically retrieve its ID. That way you don't have to worry about binding variables and scoping issues... just figure out which div contains your image and get the ID at run time.
Try:
image.onclick = (function() {
var currentD = currentDivId;
return function() {
instance.doSomething(currentD);
}
})();
Hope it helps

Categories