Collection item knows about collection it is contained - does this smell? - javascript

Allright, this might be a strange question and maybe I am heading the wrong direction, but here is my problem:
I have a SearchForm object which holds a collection of Tag objects. When a Tag object is clicked by the user, it highlights itself and triggers an event. The SearchForm class listens to this event and submits itself. The Tag object has no relation to the SearchForm.
So far, so good.
Now some Tags must activate other Tags when clicked. Each Tag knows what other Tags it must activate. But in order to do so it must KNOW about the whole collection of Tags held by the searchform.
Would it be "bad" if a Tag instance (= collection item) has a reference to the complete list of all other Tags (= collection)?
Of course some something like this would be doable:
Tag is clicked -> SearchForm is notified -> checks if the clicked tag must activate some others -> SearchForm activates the needed Tags itself.
But this seems a bit akward, or not?

It doesn't sound like there's anything wrong with that. If there's an item in a collection that needs to know about other items in the collection, it's perfectly reasonable for it to know about the collection as a whole as well.
Most GUI frameworks, and the DOM itself that presumably you're working with, have collection items that know about the collection they're in (in the DOM, on any element, you can call parentElement to get its parent).
In general, it's good if objects don't "know" about more than the minimum they need, in order to reduce coupling. But if an object does need to know about something, giving it a reference to that isn't unreasonable.

It's not uncommon for an item in a collection to know its whereabouts... think linked lists or trees. If you don't want the tag to know the whole list you might add a reference to its related tags only.

I think it's just an observer design pattern.
I don't know javascript but I guess it should be doable.
In any case avoid hard-coding your list.

Related

How to manipulate precise element of an array with redux

Today,I tried to make a list with redux where you can add and remove elements as you want visible here. My list is in fact an array updated every time user click on "Add to the list" or "Remove last added element".
Now I try to do one thing but I don't know how to do it. Indeed I what I wanted to do is, if for example the user try to add Tristan again, the FromControl with Tristan became 'sucess' (I use bootstrap too) but I don't know how to reach this element precisely, because if I used a variable in my reducer and i said the style of my FromControl depends of the state of this variable, every FormControl will become 'sucess'.
Thanks in advance for your help :)
(Sorry for my english level too)
You can use Array.prototype.findIndex() to get the index of the element in your array and work your way up from there.
I see as well that you have a lot of warnings in the console, I suggest you to add the key in your components when inside a foreach and move the setState calls to componentWillMount or another appropriate place.

Imitating a click on a dynamically added element with vanilla JavaScript

I have a ReactJS-based website which I wanna navigate programmatically. Basically, the workflow is looped:
Click on Element1.
The web page code is dynamically altered, during which Element2 is added.
Click on Element2.
Etc, until, after clicking on ElementN, the web page returns to the initial state and Element1 is displayed again. Clicking on those elements is what I wanna automate from within the website itself.
I have an access to the JS file that is responsible for the website contents creation and alteration. I can locate the code which describes the elements I'm interested in, and add any extra event listeners if need be.
I'm almost completely new to the client-side development, so my approach to solving this task is purely intuitive. So far my idea was to add an event listener for some sort of "onAdded" event which would fire when the element is added to DOM, and from that listener call the "onclick" listener (or dispatch the "click" event in some other way). However, i can't find any events that would indicate an addition to the DOM tree.
So, strictly speaking, i have two questions:
Is the approach described above viable (and adequate)? If so, then how exactly do i accomplish it?
If i'm doing it all wrong then what would be the right way to accomplish my task?
Edit 1
As per Matthew Herbst's suggestion, I looked into React lifecycle methods like componentDidMount. Turns out, the elements I wanna automate clicking on are not independent React component but some other component's contents added inside the render method with a huge chain of createElement calls.
So now the problem switches from detecting a moment when a particular element is added to the DOM structure to finding a way to interact with it.
The easy (and ugly) way to do it, as I currently see it, is to use the window object from componentDidMount, locate the element I wanna click by its data-reactid attribute (which is a string of dot-separated digits which, from what I can tell, is generated dynamically and reflects the element hierarchy) and then dispatch the required DOM event.
It might work, but if the document structure changes then the values of the data-reactid then it's all broken again. I would prefer to somehow dispatch the React's own onClick event properly, but I don't know how. I tried calling the function that gets passed to the createElement method as a value of the onClick property from componentDidMount, but for some reason it doesn't work.
I have also tried the method of interacting with DOM described in this article, but in my case the ReactDOM object doesn't seem to be defined.
Since I'm not much of a client-side developer, especially not a React guru, I don't really see the whole picture of how the website's client logic is working, and the code I'm working with seems to be minified/obfuscated to make it even harder. So if anyone could provide any specific suggestions without sending me to read all the React documentation, I'd be grateful.
Okay, I'm not sure if a question as profane as mine should be answered at all, but it looks like I got it figured out.
The minified/obfuscated code I had to deal with still had prominent features of a React application, such as objects with series of callbacks like render, componentDidMount or componentDidUpdate. So, just like Matthew Herbst suggested, I looked into the things they do.
The elements clicking on which I needed to automate were created inside the render methods by long chains of createElement calls which looked something like this:
T["default"].createElement("li", null, T["default"].createElement("div", {
className: P["default"].img
}, T["default"].createElement("img", {
src: n(600),
alt: ""
}), T["default"].createElement("b", null , "+3")), T["default"].createElement("h4", null , "«Header text»", T["default"].createElement("b", null , "+3")), T["default"].createElement("p", null , "Description"), T["default"].createElement("div", {
className: P["default"].btn
}, T["default"].createElement(A.Btn, {
mod: "info",
onClick: this._router.bind(this, "/gtr", "gtr")
}, "Play")))
I should have posted that code in the original post, but back then I didn't really understand what's going on here.
It turns out, the object referred to by T["default"] is a React object, meaning that T["default"].createElement calls were actually equivalent to the React.createElement ones.
Then, the article by James K. Nelson helped, which explained that in order to locate a specific child of a component I need to assign a ref attribute to it. I needed to access that "Play" button, so I tried adding a ref property to what looked like its descriptor object, so it would look like
T["default"].createElement(A.Btn, {
mod: "info",
ref: "automatedElement1",
onClick: this._router.bind(this, "/gtr", "gtr")
}, "Play")
, and it worked. Now, inside the componentDidUpdate method I could use the code like
if (this.refs.hasOwnProperty("automatedElement1")) {
var buttonElement = this.refs.automatedElement1;
}
Unfortunately, I didn't quite understand how to get from this object to its DOM reflection, but by simply studying its contents I managed to find a property which corresponds to the value of the data-reactid attribute of an HTML element of that button. So then I found no smarter solution than to acquire the element's DOM node by using the document.querySelector method:
var buttonNode = document.querySelector('button[data-reactid="' + buttonElement._reactInternalInstance._rootNodeID + '"]');
if (buttonNode) {
buttonNode.click();
}
This might be a bad solution, but that's the solution I managed to find in my situation, and it works. Hope it helps anyone who had a rough encounter with a React application and didn't know where to start.

Tokbox session methods inaccessible

I am getting a javascript object which contains method list but I am not able to access method.
I am integrating tokbox api and i want to call unpublish function when user wants to disconnect the stream.
Please find attached image of my object and whole function list. Please give me solutions as soon as possible.
I don't see the problem from the screenshot attached. The session.unpublish(publisher) method should work as expected. If it is not, can you please show what the errors or the bad behavior look like? Are you passing in the Publisher object? Also be aware that just because you unpublish, does not mean the video element on the page will disappear, for that you must call publisher.destroy(). Lastly, the most simple solution would just be to call session.disconnect() and that will automatically clean up by unpublishing and destroying the publisher.
I do see another error related to a parameter you passed to either OT.initPublisher(element, properties, completionHandler), session.publish(element, properties, completionHandler), or session.subscribe(stream, element, properties, completionHandler). In one of those, as the element parameter, you are passing a reference to window rather than a valid element from the page. You might also have intended to use a String that matches the id attribute of an element on the page. Please fix that.

Finding the javascript that changes a DOM element

So, I am trying to find the part of the JS where a certain element is being changed. I have looked around and I can't find a way to see how those events are handled.
The scenario is: there is a hidden field with a certain value. When I submit the form, the value changes right before being submitted.
What i am looking for is the method that changes that value.
Any advice on how to approach this would be very helpful as I am not very good when it comes to JS. Oh, and it looks like the code is obfuscated so most of the function names are one letter .
The approach I use in these situations is to examine the HTML around the area that is being modified, note all possible ways that code could find the appropriate DOM elements (form names, id values, class names, etc...) and then look through the code to find where it might be querying the DOM to find the DOM element that is being changed using one of these identifiers. Since the identifiers can't be obscured, they should be in the code in normal English the same as they appear in the HTML.
In addition, you can make a list of all event listeners that are being set in the code and pay particular attention to event listeners on any objects near the one being changed. Since it's a form submission, you can look for the submit event or click event on a form submission button.
When you see event handlers that you aren't sure whether they are involved, you can simply set a breakpoint in them and see if their code is hit during the action you are investigating. I often find it helpful to make my own copy of the code in my own editor and start adding code comments to it as I find out what something does or how it works. This gives me more of a running knowledge base rather than having to just remember everything. This is even more useful when the variable names have all been obscured.

oop in javascript binding dom elements to objects

Hi I really could do with a point in the right direction with this question.
I'm trying to fathom object orientated javascript, but am having trouble getting my head around binding dom elements to objects.
I would like to make a little animated widget type thing for my web page. the widget will be just simple drop down tabs , (like tabs from an actual folder) I want the tab to drop down a bit with a mouseover event then raise up with mouseout.
here is my current implementation, it doesnt work well at the moment it's just a mock up
http://bombinglish.com/
I want to make a class for the tabs , which will include the open and close animation methods, methos to add events, and other necessary fields. then instanciate a new object for each tab. but how do I do I tell each object that it must must respond to the corresponding mouse events, or to put it another way how do I bind the DOM element to the object?
If you are using Javascript just for presentation logic, then I don't think it's worth anything to try and get wild with OO.
If you have that at the top of every page, you could simply label the tabs with a unique class name. Then in your Javascript file you bind a mouseover event on every DOM element with that class name.
Perhaps, others have differing opinions on this however.

Categories

Resources