last day (17 days later) » 

10:15 PM
1
A: Ideas to deal with dependencies in a component-based web architecture

SamuelMy approach with React is a solution to a very similar problem as what you're describing. With React components the class constructor is used by the framework to pass element properties from the parent component. To pass additional non-property dependencies I introduce a "factory" function. expo...

 
It's a very interesting approach, a clean way to separate both kinds of arguments. Could you comment on your personal experience so far using it?
A different question -- how would you handle the dependency of the h() function (and those using it for conciseness, such as button()) in document? I find it a tricky case, because they feel like (are?) pure functions, so using them directly seems harmless, but at the same time document will not be available during unit tests, unless run in the browser. And since they are used quite a lot, and there are many of them, including them as part of the factory is quite a pain in the ass.
 
It's worked great for us. I don't follow your other questions.
 
Sorry, I must have clarified that I was referring to the JS Bin code that I linked in the original question. There you can find a function h() that takes in a tag name, a map of HTML properties, and an array of children, and returns an HTML element -- and uses document.createElement() for that. And also functions such as button(), which are partially applied versions of h() with a fixed first argument, like "button". My idea included having one of such functions per HTML element, in order to have type-safe(r) HTML, constructed by the components themselves.
 
document is a global. I think you shouldn't use it directly. You should have something like function h(createElement, ...) and pass in document.createElement in your composition root. As you said, using the global directly will be troublesome for unit tests. Passing in the function is more flexible. If you find you need to access more of the document, IMO you should still pass document as a parameter instead of referencing the global.
You can use currying to your advantage here. E.g. function h(createElement) { return function(tagName) { return function(props, ...) {...}}} and partially apply (at your composition root) const el = h(document.createElement), then you can very concisely create one for each element const div = el('div')
 
So if a component (e.g. a login form) needs form(), input(), button(), div(), label(), strong() and hr(), it should just require them and not hard-code them, right? In this particular case it feels like too much. These are normally dependencies completely hidden in HTML files or strings.
 
10:18 PM
I see what you mean
 
10:31 PM
I think what I would do is have an object const html = {div, form, input, button, ...} that contains all HTML elements. Create this object in your composition root. Then in your login form component, you would take it as a parameter const loginForm = (html, authClient, ...) => { html.form(...html.input(...)) }. For syntactic sugar, you can copy the prototype of html to have all the element types without having to write html. each time.
 

  last day (17 days later) »