The Roberto Selbach Chronicles

About |  Blog |  Archive

Blog

How do I add an unknown attribute to an element in ReactJS?

There’s this project I’ve been working on in ReactJS and Chrome and I needed to use a <webview> component. In case you’re not familiar with <webview>, it looks something like this —

 <webview src="https://robteix.com"></webview>

One of the coolest features of <webview> is the ability to isolate scope or partition it. When you use a partition, all cookies, local and session storage, etc, will be stored separately from other partitions. All you need to do is add the partition attribute. So I had something similar to this inside one of my components —

return (
 <webview id="foo" 
 src="https://somewebsite.com/"
 partition="persist:foobar" />
);

To my surprise, multiple <webview>s were sharing the same session data. Not good. A quick glance in the app storage directory told me that no partition was being created. What’s wrong?

We can look at the HTML output for hints —

 <webview id="foo" src="https://somewebsite" class="MyComponent__component___3U2KV" data-reactid=".0.0.0.2:$MyComponent.0" tabindex="-1"></webview>

No partition to be found. The reason is React doesn’t know what to do with that attribute and as a result it is not output. There are good reasons for this, but the main one is that properties may (and often do) work differently accross browsers and React needs to be able to deal with this.

But how can we add the attribute that we need then? You could add some JavaScript to get the element but that’s not very reactive. The reactive way to do this is to leverage ref, which can provide a reference to an element.

 <Element ref={somevar} />

In this code, somevar will hold a reference to <Element>. Better yet, just use a function instead.

 <Element ref={function(e) { e.Something(); }} />

Or in ES6 syntax.

<Element ref={(e) => e.Something() } />

Which finally takes us to our problem: how do we add the partition attribute? Easy peasy.


return (
 <webview id="foo" 
 src="https://somewebsite.com/"
 ref={elm => elm && elm.setAttribute('partition', 'persist:foobar')} />
);

And that’s it, a simple way to add unknown attributes to elements in React.

Clashing method names in Go interfaces

I wrote about how the Go and C# compilers implement interfaces and mentioned how C# deals with clashing method names but I didn’t talk about how Go does it, so here it is.

Two interfaces with the same method name that need to behave differently is very likely a sign of bad API design and we should fix it instead. But sometimes we can’t help it (e.g. the interfaces are part of a third-party package). How do we deal with it then? Let’s see.

Given two interfaces

type Firster interface {
    DoSomething()
}

type Seconder interface {
    DoSomething()
}

We implement them like this

type MyStruct struct{}

func (ms MyStruct) DoSomething() {
    log.Println("Doing something")
}

We can run this little test here to verify that MyStruct implements both interfaces.

But what if we need DoSomething() to do something different depending on whether MyStruct is being cast as Firster or Seconder?

Go doesn’t support any kind of explicit declaration of interfaces when implementing methods. We can’t do something like, say

type MyStruct struct{}

func (ms MyStruct) Firster.DoSomething() {
    log.Println("Doing something")
}

func (ms MyStruct) Seconder.DoSomething() {
    log.Println("Doing something")
}

That won’t work. The solution is to wrap MyStruct with a new type that reimplements DoSomething(). Like this

type SeconderWrapper struct {
    MyStruct
}

func (sw SeconderWrapper) DoSomething() {
    log.Println("Doing something different")
}

Now when we need to pass it to a function expecting Seconder, we can wrap MyStruct

ms := MyStruct{}
useSeconder(SeconderWrapper{ms})

That will run the DoSomething() from SeconderWrapper. When passing it as Firster, the original DoSomething() will be called instead. You can see this in action here.

Interfaces in Go and C#

I make no secret of the fact that I love Go. I think it’s a wonderfully designed language and it gave me nothing but pleasure in the years I’ve been working with it full time.

Now however I am working on a project that requires the use of C#, which prompted me to realize something.

When people ask about Go, most people talk about channels and concurrency but I think one of the most beautiful aspects of Go is its implementation of interfaces.

To see what I mean, let’s define a simple interface in Go.

type Greeter interface {
    Hello() string
}

Now say we have a type that implements this interface

type MyGreeter struct {}

func (mg MyGreeter) Hello() string {
    return "Hello World"
}

This is it. myGreeter implicitly implements the Greeter interface and we can pass it along to any function that accepts a Greeter.

func doSomethingWithGreeter(g Greeter) {
    // do something
}

func main() {
    mg := myGreeter{}
    doSomethingWithGreeter(mg)
}

The fact that the implementation is actually important, but we’ll get to that. Let’s first do the same thing in C#.

interface Greeter
{
    string Hello();
}

And then we create a class that implements the interface.

class MyGreeter
{
    public string Hello()
    {
        return "Hello world";
    }
}

We quickly find out that the compiler doesn’t like this.

public static string doSomething(Greeter g)
{
    return g.Hello ();
}

public static void Main (string[] args)
{
    MyGreeter mg = new MyGreeter ();
    doSomething (mg);
}

The compiler complains that it cannot convert MyGreeter to type Greeter. That’s because the C# compiler requires classes to explicitly declare the interfaces they implement. Changing MyGreeter as below solves the problem.

class MyGreeter : Greeter
{
    public string Hello()
    {
        return "Hello world";
    }
}

And voilà, everything works.

Now, we might argue that it is not much different. All you have to do is to declare the interface implemented by the class, right? Except it does make a difference.

Imagine that you cannot change MyGreeter, be it because it’s from a third-party library or it was done by another team.

In Go, you could declare the Greeter interface in your own code and the MyGreeter that is part of somebody else’s package would “magically” implement it. It is great for mocking tests, for example.

Implicit interfaces is an underrated feature of Go.

Update: someone on Twitter pointed me to the fact that C# not only also has implicit interfaces but that this is the default state of things. That is true in a literal sense, but it’s not the same thing.

Imagine in our C# above, we have a second interface.

interface IAgreeable
{
    string Hello();
    string Bye();
}

(Yes, I was also told that in C# we should always name interfaces like ISomethingable. I disagree but there it is.)

We then implement our class thusly

class MyClass : Greeter, IAgreeable
{
    public string Hello() {
        return "Hello world";
    }
    public string Bye() {
        return "Bye world";
    }
}

It now correctly implements both interfaces and all is well with the world. Until, that is, the Hello() method needs to be different for each interface in which case you will need to do an explicit implementation.

class MyClass : Greeter, IAgreeable
{
    string Greeter.Hello() {
        return "Hello world from Greeter";
    }
    public string Hello() {
        return "Hello world from !Greeter";
    }
    public string Bye() {
        return "Bye world";
    }
 }

And then the compiler will call the appropriate Hello() depending on the cast.

public static string doSomething(Greeter g)
{
     return g.Hello ();
}
public static string doSomethingElse(IAgreeable g)
{
    return g.Hello ();
}
public static void Main (string[] args)
{
    MyClass mg = new MyClass ();
    Console.Out.WriteLine(doSomething (mg));
    Console.Out.WriteLine(doSomethingElse (mg));
}

This will print

Hello world from Greeter
Hello world from !Greeter

Personally I consider two interfaces with clashing method names that need to behave differently a design flaw in the API, but reality being what it is, sometimes we need to deal with this.

Invincible breaks my heart

Spoilers abound. You’ve been warned.

From the very beginning, Robert Kirkman maintained that Invincible was his attempt at doing the whole superhero thing right. There is a running gag in this book that on every cover (at least for a lot time if not since the beginning), they take a little jab at the superhero genre as done by other houses.

As news appeared that there would be a reboot, Kirkman was quick to declare that he was not going to be a dick to his readers and would not erase the whole timeline. By calling the arc “REBOOT?” with a question mark, he could not have made this more clearer. Also, the cover tagline:

img2015-12-16_04

And so we reach the end of the arc and Kirkman did keep his promise: the timeline was not erased. But maybe it should? That is the question that he leaves us with.

Mark is taken back to just before he gets his powers. He then deals the best he can with what he knows is coming: Nolan’s attempt at conquering the world for the Viltrumite Empire and the consequent deaths of so many in the process. That’s the “hero stuff” and although it’s well done, none of it will matter.

Mark has also to deal with being young again, living with his parents. His wife of many years now barely knows and definitely doesn’t care for him. And his daughter wasn’t born yet. How do you deal with this?

During the first two issues of the arc, Mark’s personal life was mostly a B plot. But in this final issue, it becomes central.

img2015-12-16_45

Mark gets a chance to go back to his original timeline, to his wife, to his daughter. But he’s asked for a sacrife. A hero’s sacrifice.

The beings that brought Mark here explain that by setting himself in another path, he can fix the future, he can fix all the things that happened to Earth in the original timeline. All he has to do is make the choice.

img18.21.24

But he says no. Mark wants to go back to his wife and daughter. There is nothing that can make him change his mind.

He doomed his planet and he is a disgrace, they say. I can live with that, he responds and goes back only to find desolation where the battle against Thragg is apparently finished – and apparently lost — I suppose we’ll learn more about that soon.

And of course, Kirkman had to throw one extra punch at the guy. As a father, the reveal at then end of what Mark has lost is heartbreaking.

Invincible remains the only book that has never once disappointed me in any of its arcs. This is amazing for a story ongoing for over 10 years and 126 issues.

Now excuse me while I go hug my daughter.

The Evolutionary Psychology Nonsense

I have a friend who is all into the whole evolutionary psychology fad. It’s useful when you want to rationalize bad behaviour. I once told him that evolutionary psychology was pseudoscience to which he replied saying that I was just trying to negate the world as-is.

But apparently I’m not alone, as Jonathan Marks writes (emphasis is mine) —

I can’t shake the feeling that the methodologies I have encountered in evolutionary psychology would not meet the standards of any other science.  For a notable example, it is apparently a revelation to evolutionary psychology that one cannot readily generalize about the human condition from a sample of humans that is Western, Educated, Industrialized, Rich, and Democratic. Perhaps this was news in psychology – creationist, evolutionary, or otherwise – but, sad to say, everybody else who works with cultural diversity knew that a really long time ago.

Avoiding Avoidance Behaviour

I am currently trying a new approach to deal with my social phobia. Basically it involves avoiding avoidance behaviours. You see, people with social anxiety tend to avoid problematic situations and run to metaphorical safe places. After a while, the avoidance behaviours become almost automatic, almost imperceptible.

Almost but not quite.

We behave so without thinking but we recognize the behaviour while we’re doing it. And that’s exactly when we have to force ourselves to avoid avoidance. It is very difficult and the temptation of avoidance is almost irresistible. The problem, of course, is the more we avoid things, the harder it is to stop doing it later in life.

Last night I posted something to Facebook —

https://www.facebook.com/robteix/posts/10153208453849048

The voices of social anxiety immediately started working in my head. “FriendA will mock at you,” they shout. “FriendB will think you’re pathetic.” And so they went. I came this close to deleting the post before stopping and forcing myself to ignore the voices.

It is not easy. It is so not easy that I am writing a blog post about it. Social phobia makes my mind work against me: it constantly attacks me, my self-esteem, and my confidence. It would be so much easier to just delete the post.

Dealing with social anxiety involves many counter-intuitive measures: it forces socially anxious people to go against what our own brains tell us is not the safest route.

I need to keep working on it. I’ll need to continue to force myself into doing more of what I desperately want to avoid. Let’s see how it goes.

Why do Salespeople Believe in Magic?

File this one under techies complaining about non-techies. Over the years, I have noticed a pattern with salespeople, they have a firm belief in wishful thinking. They honestly believe that wishing something to be true will magically make it so.

Wishful_Thinking

The specific pattern I noticed many a time goes something like this.

The customer wants something done and goes through their account manager to request that. The account manager — a fancy name for salesperson — commits to a date without talking to the developer first. They then go to the developer and tell her something to the effect of “yeah, I’m going to need that by Friday morning.” The exasperated developer explains that this is not feasible and the account manager responds by simply repeating that they will need it by Friday. They usually leave at this point satisfied that everything is fine.

Come Friday, the account manager is then horrified to discover that the feature is not ready. “But we made a commitment with the customer,” they’ll say, emphasizing the “we” that never was.

This has happened some many times in my career that I should no longer be surprise and yet I still do. Every time.

Of course, what they are really doing is trying to put pressure on the developers so that they will hurry up and deliver on the desired timeframe. And to be fair, it can sometimes work, but if the developer tells them in no uncertain terms that the deadline is not feasible, then the salesperson is taking the risk by herself.

By committing to a date with the customer before talking to the developer, the salesperson has already taken a big risk. They will then try to spread that risk by sharing it with the developer. Since the developer never had a chance to agree with that in the first place, it is only fair that she should be able to refuse to take the risk if she doesn’t believe it is worth it. Why should she?

And yet, we developers often accept the risk by being passive and simply accepting it. This problem can be exacerbated by managers who are also passive. Many years ago I worked at a company where the engineering power that be were submissive to the sales department, which led to some of the worst experiences in my life as a developer, including the Project From Hell.

At the time, I led the engineering services group, so whenever a new project came about that required software development, it had to go through me for analysis. Another group leader analysed the infrastructure projects. Then one day this large project showed up on my desk. I looked over it along with the infrastructure guy and we agreed that it was a monster of a project, including developing a huge distributed nationwide (Brazil) infrastructure, a huge system developed from scratch, and a lot of technology transfer and end-user training.

The project had some timeframes attached to it and although they were tight, they were not what immediately caught out eyes. We saw the pricing they were offering the customer and it was clear to us that it was low. We raised the issue but were told not to worry about it. There are valid business reasons to do projects at a loss sometimes, so it was okay, except the exact wording to us was, “please limit yourselves to your little expertise sphere.” Ok then.

We talked to our teams and we committed to the dates defined in the project documentation. Again, it was a little tight but feasible: we would have many months to get things ready for initial deployment.

About a week after we approved the statement of work, I received a call from the customer. At this point, I had not yet engaged the customer at all, so they had gotten my phone number from their sales rep. The customer was possessed. This person I had never talked to before was shouting at me on the phone that we were late. It took me a while to call him down and understand what the issue was.

As it turns out, the sales team, in an effort to get the customer’s signatures before the end of the quarter, changed the statement of work after we had gone through it, moving the dates to right that very moment. We had not even started working on the project yet and the customer was expecting it to be ready right then. We were late before we even started.

Many stressful meetings later we managed to agree on some new dates, but they were much tighter than the ones originally in the statement of work and would required us to outsource parts of the project to a contractor to help speed up things. Incidentally, what we paid the contractor for only a part of the project was more than what our company made on the project. All because the sales team wanted to make sure they got their commission in that quarter.

The people responsible would eventually be let go of the company, in great part due to this, but that did not prevent the company from losing at least an order of magnitude more than what it made from that project.

And still, I continue to see salespeople ignoring the developers and then trying to share the fallout. Developers need to stand firmly by their professional evaluations of deadlines and technical feasibilities.

Of course, if you turn out to be wrong, all of this is moot.

Goodbye, Mr. Spock.

Leonard Nimoy

I am sad. The New York Times

Leonard Nimoy, the sonorous, gaunt-faced actor who won a worshipful global following as Mr. Spock, the resolutely logical human-alien first officer of the Starship Enterprise in the television and movie juggernaut “Star Trek,” died on Friday morning at his home in the Bel Air section of Los Angeles. He was 83.

I am actually sad. As much as Star Trek was a part of my life, I had not felt this way when other cast members passed away in the past.

I suppose Nimoy was different somehow. My theory is that as Spock, he would (almost) never smile and that made his rare smile that much more important. When I think of Nimoy/Spock, it is his smile that I picture in my mind. When out of character, he was always smiling. This contrast forces an emotional connection or something. I don’t know.

What I do know is I am sad. For whatever’s worth, Nimoy was a part of my life.

You’ll be missed, Mr. Nimoy. I have been, and always shall be, your fan.