Why is toggling a search box in a header so difficult in Angular 2?

In Angular 2 I have the following pseduocode…

<header>
<form class="searchContainer" [ngClass]="{'visible': showSearch, 'invisible': !showSearch}">
...
</form>
</header>

As you can see I have a header with a search form container that has the class ‘visible’ when the variable ‘showSearch’ is true, and ‘invisible’ otherwise. As a component by itself with this html, this works fine. When the user clicks the search icon showSearch is set to true and the form shows.

Now the issue comes when I want to hide this container again. I want to set showSearch to false and thus hide the container when the user clicks anywhere that isn’t the header (ie. the body of the page).
Now in jQuery, this would be easy. On click of the body, you would find the element with ‘.searchContainer’ and removeClass(‘visible’).addClass(‘invisible’) right? Easy.

Except this is Angular 2. We don’t have jQuery (or want to use it) here. Normally what I would do in this case, is to have something like this in the parent component that contains the header component:

<app-header [showSearch]="showSearch"></app-header>
<body>
..
</body>

That’s the HTML. I pass the showSearch variable down from the parent to the child and toggle it with the parent right? That’s how normally it works. One way binding. (If the child needs to talk to the parent it uses event emitters instead).


@HostListener('click', ['$event'])
closeSearchBox(event) {
const toElement = event.toElement;
let insideHeader = false;
let node = toElement;
while (node != null && node.classList !== undefined) {
if (node.classList.contains('header-container')) {
insideHeader = true;
}
node = node.parentNode;
}

if (!insideHeader) {
const searchBox = this.elementRef.nativeElement.querySelector('.search-container');
const searchMenu = this.elementRef.nativeElement.querySelector('.header-menu-list');
if (searchBox.classList.contains('visible')) {
this.showSearch = false;
}
}
}

So this should work right? I have an HostListener on the parent (that’s really the whole body of my app) so if the user clicks anywhere it will check to see if the element is outside the header (because we dont want to close it if its inside the header), and close the search container if it is.

Problem is… it didn’t work. I don’t know why. I searched StackOverflow, Angular Docs, scoured Google etc nothing. I even tried using EventEmitter but thats usually only from child to parent and not parent to child. Two-way bindings? nope doesn’t work either. It *should* just work inherently as part of Angular’s single way binding. Maybe the HostListener is outside the Angular Zone and I can use ChangeDetectorRef to detectChanges? Nope. That didn’t work either.
I *could* use a service and just subscribe to that service from the child component … but thats kind of overkill for ONE variable change to toggle a search box.

So finally. I had to make a solution that is not so elegant, and doesn’t use any variables or bindings. But it works.

<header>
<form class="searchContainer invisible">
...
</form>
</header>

So I took a jQuery-like approach of just toggling the class manually with ‘elementRef.nativeElement.classList’ instead. Its not as pretty as using bindings, but at least this way it works.


toggleSearchHeader(showHeader) {

if (showHeader) {
this.searchHeaderMenu.nativeElement.classList.remove('visible');
this.searchHeaderMenu.nativeElement.classList.add('invisible');
this.searchHeaderBox.nativeElement.classList.remove('invisible');
this.searchHeaderBox.nativeElement.classList.add('visible');
} else {
this.searchHeaderMenu.nativeElement.classList.remove('invisible');
this.searchHeaderMenu.nativeElement.classList.add('visible');
this.searchHeaderBox.nativeElement.classList.remove('visible');
this.searchHeaderBox.nativeElement.classList.add('invisible');
}

}

I have to substitute changing one variable showSearch with a whole method that does janky DOM crap and..


@HostListener('click', ['$event'])
closeSearchBox(event) {
const toElement = event.toElement;
let insideHeader = false;
let node = toElement;
while (node != null && node.classList !== undefined) {
if (node.classList.contains('header-container')) {
insideHeader = true;
}
node = node.parentNode;
}

if (!insideHeader) {
const searchBox = this.elementRef.nativeElement.querySelector('.search-container');
const searchMenu = this.elementRef.nativeElement.querySelector('.header-menu-list');
if (searchBox.classList.contains('visible')) {
searchBox.classList.remove('visible');
searchBox.classList.add('invisible');
searchMenu.classList.remove('invisible');
searchMenu.classList.add('visible');
}
}
}

So yeah as you can see those are the changes I needed to get it to work. For some reason, using a variable inside `HostListener` and passing that down to the child component doesn’t reflect the bindings. So I have to use a more archaic way instead. Not only that but its much more difficult to test with unit tests now that it relies on the DOM instead of an Angular variable. Bleh. If anyone knows why this is, let me know please! comment on this post..

Response to recent Google employee’s memo..

As many people on the internet know, a few days ago a Google employee’s internal memo was leaked out.. and there has been a big fuss about it.
Not only was there so much hate on that guy, claiming that he was ‘misogynist’ and ‘male chauvinist’ but his name and picture were actually leaked by the press as well! If this wasn’t character assassination and defamation I don’t know what is.

So, I’ve actually read the memo, and while I disagree with portions of it, for the most part I agree with him. My opinion is not a popular one in the liberal majority Silicon Valley. But I can assure you there is nothing that sexist / misogynist about what he wrote. First off, people should stop using that term so frequently because it literally means someone who hates women. This memo does not come off to me as someone who hates women. The main point he was getting across is that 1. conservatives are discriminated against in the tech industry and 2. Women’s biological differences with men are the reason why there aren’t as many women in the tech industry

His first point is actually true, since Google promptly fired him after that memo leaked. As a private company they have all the right to do that, but it goes to show what happens when you have an unpopular conservative opinion in a sea of liberal opinions. Yes he had freedom of speech, but in the end if he violated Google’s code of conduct they had every right to fire him. I just don’t think it was fair since his opinion was actually quite valid.

Secondly, as an Engineer I am usually very skeptical of claims unless they are backed by science. I don’t believe in conspiracy theories like area 51 / aliens or chemtrails or 9/11 theories or moon landing hoax theories or stuff like that. I don’t believe in superstitions like Feng Shui or chinese medicine (pseudoscience) or go to tarot readers or astrologists since I don’t believe in the supernatural. I don’t believe in ghosts or monsters. I DO believe in global warming, because that’s backed up by science.
Now, while this is very hard to prove by science, it is actually common sense to everyone that men and women are not the same. Our bodies are built very differently. Our brains are wired very differently. There is a gender difference in humans just like there is in every other animal. That is quite easy to accept. So I don’t understand what is so misogynist or hard to understand that differences in the way each gender thinks is the reason why certain genders perform certain roles?? Being different is good. There’s nothing wrong with being different. If people really want a society where men and women are treated exactly the same, I would recommend those people to move to a communist society. Perfect gender equality there.

Men usually perform roles with physical labor like construction or mining, or roles that involve analytical thinking like mathematics, science or engineering. That is not to say women can’t do those roles, but definitely men have a dominant advantage in those roles. Women on the other hand, are much better at serving and caring for people. That’s why women tend to be clerks, cashiers, customer service reps, broadcasters, receptionists, nurses, etc. They are better suited for those positions than men. There is nothing misogynist or women-hating about this train of thought, this is the way that I feel after looking at other animal species and interacting with humans. Male lions don’t ask female lions to do the same task, they each have their own responsibilities. So why is it so unacceptable for humans to be the same? Even in engineer crazy India and China, there are more males than females in engineering. They have no reason to discriminate against women there (Asians are notorious for pushing that field onto all their children), yet there are still more males. Why? because men and women’s brains are different, that’s why. Its not hard to understand why. Anyone who’s been in a relationship before can tell you that women’s minds are way more emotionally complex than a man’s mind.

Because people like to be social justice warriors. They like to think that taking the stance that women are the victims of social constructs, that women can do anything men can do, and somehow that will make others think of them as better people and supporting gender equality more. Its total nonsense, just like third-wave feminism. I support equal pay for equal work and gender equality, but I do so while acknowledging that men and women have different roles in society. People are just fooling themselves, they are denying science and biology because ironically, they are the victims of the liberal social construct, the very social constructs that they fight against. Do they also believe that social constructs are the reason why men can run faster and jump higher than women can? The liberal echo chamber of the Bay Area puts pressure on people to care or think about minorities, disabled, women, etc to help anyone who’s “oppressed” historically, even if it goes against science or what they actually believe. This is unfortunate, and the firing of this man for his memo (which is personal btw it wasn’t meant to be leaked), just goes to show that if you do not reflect this liberal echo chamber, then you will be punished for it in America. Those are just my 2 cents on this issue.

tldr; I’m not a misogynist, I’m for gender equality, but I also believe men and women are biologically different and that makes them better at certain positions for each gender. This is backed by science and I support it.

Korea vs China what’s the difference?

A lot of differences. Some Chinese people say that Koreans “stole” Chinese culture but in some ways Korea is more Chinese than modern day China is.

-Koreans follow strict Confucian principles more than modern day Chinese do. This was true even back in the old times when Qing China and Joseon Korea existed. Koreans more than any other race stick together. They have this sense of ‘togetherness’ that does not exist to the same extent in modern day China. For example, somebody fall down in the street in China. Does anyone care? If it happened in Korea many people will help them. Do Chinese people really care about how other people act behave or look like? Maybe, but not to the same degree Koreans care.
-Loyalty and politeness. Korea takes a lot of cultural cues from Japan. This is one of them.. Korean companies value loyalty and expect the workers to stay at their company their whole life, just like in Japan. Its considered disloyal to quit the company or change companies. This does not happen in China. Also social cues like ‘nun-chi’ 눈치 in Korea its kind of like mannerisms towards older status people doesn’t really exist in China. Koreans bow when greeting each other. Chinese shake hands much like Westerners.
-During new years or Thanksgiving Koreans (particularly the women) will dress in their traditional outfits the hanbok 한복 and traditionally prepare food for their ancestors. A lot of Korean couples also wear hanbok just for taking pictures. You will not see Chinese wear their traditional outfits for things like this. The only times I see Chinese wear qipao or traditional Chinese outfits are for stage plays, Chinese opera or for traditional type weddings, thats it.
-Language. Korean language although they used to use Chinese characters, is very different now. They use honorifics in their language just like Japanese. So talking to older or younger person is different. Not so in Mandarin chinese.
-Work culture as I mentioned is pretty different. And its more competitive. Koreans have to learn either Chinese or Japanese in high school, and because appearance is valued so much in Korea, lots of girls get plastic surgery just to have a higher chance of getting a job there. Most students study English late into the night. You’ll find that the average Korean’s English is better than the averaged Chinese’s English skill. In China its not quite as competitive due to the following fact:
-Chinese are more ambitious and bigger risk takers than Koreans are. Koreans are very socially conservative more so than Chinese. They are risk averse and would rather suicide because they couldn’t get into Samsung or a famous university than start their own company. Chinese will find another way to get a job or start their own companies. They don’t give up quite as easily.
-Koreans care about appearance a lot like I mentioned. So almost all Korean girls wear makeup, dress up, and don’t wear glasses. Their fashion styles are totally different. In China its not quite as important, BUT they focus a lot more of showing off their wealth which means buying brand name items and owning homes is more important over there.
-Koreans are a more ‘traditional’ society… the women usually stay at home to take care of children, and do cooking and cleaning, while in China these duties are shared between the husband and wife. Gender equality is slightly better in China due to communism..
-China is a very diverse country full of different races. Korea is 99% Korean. This means if you look different or act different, you are probably more likely to be noticed in Korea than in China. Korea is a very conformist society and people like to act and look the same. You will find less ‘crazy’ people in Korea than in other countries.
-Religion. 40% of Koreans are Christians and another 30% are Buddhist. Since Communism eliminated religion, very few Chinese are actually religious.
-Koreans like to export their culture to other countries like kpop or kdramas. They somewhat have to do this because their country is small and they have a limited market, so their global marketing skills are very developed. China has a big domestic market so not much need to export their music or fashion or entertainment, thats why you never about hear any Chinese pop conventions…
-Korean food is really just a subset of Chinese food. Chinese people eat almost anything. spicy things, fried things, insects, herbs, parts of frog or duck or dog or horse, etc almost ANYTHING. The cuisine really depends on part of China, but Korean food tends to be spicy, and their cuisine really is a subset of Chinese cuisine. I can say almost anything you eat in Korea can be found *somewhere* in China, but not the other way around. Very few Koreans eat actual Chinese food and instead eat “Koreanized’ Chinese food. Jajeongmyeon is actually Korean food but they think its Chinese.
-Both countries are relatively safe compared to gun crazy America, but Korea is more safe. In China there is always risk of food poisoning, people stealing stuff, getting scammed etc. In Korea you can leave your phone on a table for hours and no one will take it.

Thats just a few differences.. there are indeed MANY since I lived in both countries. Even tiny minor things, for example Koreans like to drink when they are together and Chinese play card games (Koreans dont play card games very often). Games like Mahjong are non-existent in Korea but everywhere in China.