ECO = Engineering Change Order

ECO is a common term used in Engineering. It refers to documentation process for any design changes made to an existing design to fix a bug. These design changes are usually small, so we make localized changes and document these. It's used in vlsi a lot, since early chips mostly have design bugs, which can only be fixed by making changes to the design. The issue is identified, fix proposed, then it's implemented and new design released. This is all documented as an ECO.

When we need to fix a vlsi design, we basically insert/delete gates or change wires. This alters the mask for metal layers or base layers. ECO is the process of minimizing those changes in mask, so that we don't make too many changes to mask set. If we have to make too many changes, then there's no benefit of doing an ECO. In such cases, we should start design from step 1 instead of marking changes as ECO.

The initial design for any project is named as 1p0 or A0 design. We release the mask set for this to fab, and get the fabricated chip. If the chip comes back with bugs, we try to find out if those bugs can be fixed by just changing metal masks (instead of changing base layer mask too). If we can fix bugs by just changing metal masks, it's less costly both in terms of time and money. This new design with only metal mask changes is usually called as 1p1, 1p2 or A1, A2 etc. However, if the changes are more complex, we may need to make changes to base layer masks too. This new design with base layer mask changes are usually called 2p0, 2p1 or B0, C0, etc. Thus A, B, C refers to major design changes involving base mask, while B1, B2, B3 etc refer to minor design changes involving metal mask only.

If the change can be done by changing metal layers only, then it's called "metal eco", while if it involves base mask changes, then it's called "all layer eco". so, "metal eco" are minor revisions as B1, B2, etc, while "all layer eco" are major revision as A0, B0, C0, etc.

ECO type: pre-mask vs post-mask: ECO can be of 2 types based on when the change is made in design:

1. pre-mask => premask is when mask isn't ready yet, i.e for making very small changes while the design is still not taped out. Here, no masks have been ordered. So we can make any change we want. However, we do not want to run the entire design from step 1, since we may have fixed a lot of issues manually in the design, and ripping the whole design to fix some minor issues is prohibitive in terms of cost and time. So, we put the design in pre-mask eco mode, which says that the changes will be localized to affected areas only, so do not disrupt the whole design. Keep changes as small as possible. Here we can change both metal layer as well as base layer. So we are allowed to make complex design changes here, as we have the flexibility to change any gate or wire. We use the term pre-mask to mean that base layer changes are allowed in design. So, an "all layer eco" is basically called pre-mask eco, even though mask may have already been released.

2. postmask => postmask is for making changes after the mask has been released. We find out late that their is a bug in design. In such cases, we make metal mask and/or base layer mask changes. We need base layer mask changes when the changes are extensive and more complex. These get classified as pre-mask eco, even though they are post-mask. However, if the changes are small and can be implemented by changing metal layers only, we call it "metal eco". This is what is usually referred to as "post mask". For postmask eco, spare cells are used (as it's metal only), while for premask, new cells are added or existing cells modified.

 

ECO type: Functional vs Non-Functional: ECO can be of 2 types based on what kind of change is involved:


1. Functional ECO: change the functionality of the design. i.e when an and gate is added to some logic path, that is a Functional ECO.


2. Non-Functional ECO: does NOT change the functionality of the design, but deal with timing, design rule or signal integrity. i.e when a wire is moved to make extra spacing, it's a Non-Functional ECO.

 

Both Synopsys and Cadence tools support ECO flow, so that changes can be easily made from within the tools.

For Cadence, Conformal tool is usually used for making ECO, while for Synopsys, Design Compiler (DC) tool is used.

 

 

 

Movies, Shows and TV channels

This section deals with Indian movies, shows, channels that you can avail of in USA. It also lists American shows, channels, movies that may be worth your time.To watch American movies/shows is really easy as too many options are available (listed below). Watching Indian movies/shows is little bit of work and costs a bit more.

Indian Movies/Shows: One of the first things, Indian look for in USA is watching Indian shows and movies. You can watch almost all Indian channels (i.e StarPlus, Zee, Sony, etc) here is USA, via a lot of companies. Below are some options:

1. Dish network (www.dishnetwork.com): This used to be the only provider of Indian channels for a long time. They provide you service via satellite (so you need an antenna on the rooftop). Their service is good. However they are expensive and cost you around $50/month. Definitely avoid it. I had been a dish network customer for 15 years, but recently ditched it, as there are a lot of low cost providers available. You can always call them, and tell them that you are cancelling service. To keep you they will offer you a lower price, but even with that, they are definitely expensive.

2. Sling (www.sling.com/international/desi-tv/hindi): This company is very popular, and provides Indian channels via your internet connection (streaming service). Service is good and I've never seen any interruption. It's also expensive at $60/month for Hindi gold package, which includes all channels. However, they allow you to watch on 3 TV simultaneously, so 3 people can share the same account, and bill will drop down to $20/month for each user. You need a roku player to connect to your tv depending on how old your tv is (if your tv isn't smart and hence has no wifi adapter on it + no sling app on it, then you need roku player, which can be had for $30 or less). You may not need a roku player if you have a TV which is smart (i.e which allows you to download different apps as sling, etc). Generally TVs since 2015 may not need roku player.

3. IPTV Providers: There are lot of IPTV providers whose concept is same as sling TV, but they offer you services at fraction of price. They usually cost < $300 for 5 year subscription. Comes out to $5/month, which is the cheapest streaming that you can get. There are 100's of them tageting indian customers. They have bunch of Indian movies, shows, series.They also have all channels as ZEE, Sony, Star. They also have English shows, movies. in their video section (most of them 1080p), with new ones being added weekly. So, you can watch almost all high quality Indian movies for no extra charge. The amount of content is huge. Tough all of these IPTV providers advertise their content as being superior to other, I believe they all come from same source, so their content and quality is mostly similar. Some provide their own Boxes (i.e Streaming box similar to Amazon Fire stick) or will ask you to install an app, thru which you connect to their services. Boxes provide better experience as they automatically connect. The ones with app may sometimes not connect at all.  Below are few popular ones that I've tried. Always go for 5 year plan, as they are the cheapest. If you ask them, they will gladly give you 6 months extra for free.

  1. boxiptv (www.boxiptv.xyz): They charge $270 for 5 year subscription. Comes out to $5/month, which is the one of the cheapest. They provide you both options => one with box and one without. The one w/o box costs $220 for 5 years. They allow you to stream on only 1 device with one box. For the non-box option, I'm not sure.They charge you in canadian dollars, so depending on your credit card, there may be a currency conversion fee (so use a credit card, which doesn't charge you any conversion fee). Their service is good, and interface for finding movies, shows etc was also pretty intuitive. I had them for 5 years. The only issue I found was that the streaming was laggy, and would get stuck every minute. After some investigation, it turned out that the streaming box provided by them doesn't have good pickup for routers placed at more than 10 ft apart. So, once I placed the router very close to their streaming box, I never had any lagging issue. Or even better, if you have ethernet port close by, connect the box to the ethernet port directly using a ethernet cable. That gets rid of most of the lagging issues.
  2. Rahuliptv (https://www.rahuliptv.com/): They are app based (no box). You have to download 3rd party app  "IPTV Smarters Pro" and it may not be free depending on the device. Their downlaod may also be convoluted, as the app doesn't appear for direct install. You have to download "Downloader" app, and then download some files to get the app. So you are really at the mercy of some unknown 3rd party app. Their prices are the lowest with 5 year plan for $225. I've tried their for a few months, and looks good. They allow to stream on up to 2 devices which is convenient. However, they have no customer service number or no o
    1. UPDATE 02/20/2025: 
  3. towniptv (https://www.towniptve.com/): NOTE: the webaddr has a e in end i. it's "towniptve". I haven't tried this service, but looks very similar to boxiptv. They charge $340 for 5 years, which is more expensive than boxiptv. But it never hurts to ask them to match.
  4. Misc: I keep getting phone calls from bunch of iptv providers for Indian channels. I don't know how they get my number, but they all have similar prices and hard to know whom to trust. Because once you pay the money, there's no way to recover that. They all use third party payment processors who charge extra 3% for processing. So, always use a "Chase Credit card", as Chase will cover you even after 1st 3 months. And always go for short term contract, even though it may be more expensive. These iptv providers may disappear any time.

I haven't found a cheap source of watching Indian movies. boxiptv above has bunch of Indian movies, which you can definitely watch if you get their service. So far, netflix and amazon prime also offer limited movies, but they cost more. You will be surprised to know that youtube has lots of "Full Length Indian movies" with good quality, which are absolutely free to watch.

4. Large Streaming Companies:
You will hear a lot of marketing material on how everyone needs a netflix and amazon streaming services. There are also Disney, HBO, and many others that offer their original content. All of them are very expensive (costing >$100/yr). All of them have very limited selection of Indian movies/shows. IPTV providers provide a lot of their content, so if you go with IPTV providers, you have no reason to get netflix, etc.

  1. Netflix (www.netflix.com): They have a huge selection of American movies, and about 500 or so Indian movies. Though their selection of Indian movies is not that great, they have their own produced Indian shows, documentaries, etc which are quite good. It costs around $15/month to watch on 2 TV simultaneously. So, if 2 people share it, the cost would be $8/month. You can buy discounted netflix giftcards once in a while from Bestbuy, Walgreens, etc at 20% off. Then apply those to your account and you could save 20% or more on your bills. Since netflix goes month to month, and they have free monthly trial, you might want to get netflix free trial every year, watch all the movies/shows for free, and repeat the same next year. Really no need to pay $200/year for it.
  2. Amazon (www.amazon.com): If you are amazon prime member, amazon movies is included in your subscription at no extra cost. They have even limited selection than netflix, but may be worth it for free. I would n't go and pay for this service, as you can find all the content of amazon on other subscription service (i.e on youtube, iptv, etc)

 


 

American Movies/shows: American channels (i.e ABC, FOX, etc) can be watched directly on TV by having an HD Antenna. Or also via apps if you have smart TV. They show a lot of Hollywood movies, shows, news, etc. American movies can also be watched via netlix or amazon. However, none of the latest release are available. For that you will have to go to a movie theatre. If you can wait a little longer (usually a month or two), you can watch them on DVDs.

1. redbox (www.redbox.com): They have stand alone redbox kisok outside/inside major grocery stores (kroger, walmart, etc), drug stores (walgreens, CVS, etc) and many other places. Most of the times they have coupon code for free rental. If you have Tmobile Tuesday app (by being a customer of T-mobile cellular services), about once a month, they send you such code. Also, if you sign up for their emails on their website, they will send you such codes. From time to time, you can find such codes on slickdeals.net (just search for redbox). I have never paid a single cent for renting movies on redbox, and have already watched 100 or so movies via them. Be careful with the return of the DVD though. You have until 9pm (local time) next day to return a DVD. If you miss that deadline, you have to pay next day rental which is expensive at $2/day. That is where Redbox makes most of the money.

2. Libraries: All local libraries in USA are free to join. They have huge selection of movies. If you are in one of the big cities or suburbs, you can get almost any popular movie which is more than 6 months old. They also keep a decent selection of Indian movies. This is your cheapest source for watching free movies.

3. Misc: Netflix, amazon, HBOMax, and many other streaming services provide a lot of movies and shows for a fixed monthly price. They make their own movies and shows and show it only on their platform to subscribers who pay for thier service. They charge monthly subscription fee of $10-$15 per month. However, there is no annual contarct, so you can get out at any time. What I do is to cancel the service after a couple of months, when I'm done watching all their good shows/movies. Then after a year or so, you may join again, if you see they have gotten any new shows/movies that are of interest to you. One word of caution is that these companies keep on removing their popular shows/movies from their services every month, and the one of the reason may be to force people to stay with the service long term. More info about these is in "Other Movies and shows" subsection.

 


 

Movie Websites:

Below are some of the best resources for finding everything about the movies:

IMDB: IMDB (Internet Movie Data Base) is the most comprehensive website for finding details on any movie. If you need to look for any movie mentioned below, search it on imdb and match it with year and director as there are usually multiple movies with the same name. You should be able to find both Hollywood and Bollywood movies here.

Wikipedia is other very good resource for almost anything.

Rotten Tomatoes: This website has gotten very popular recently as it relies on people's vote and critic's vote to get the rating.

More categories under entertainment show popular bollywood and hollywood movies. I've also listed cheap theaters available around USA.I'll add more sections as I find more material.

 


 

Chip design - clock tree

Clock is the most important signal in a chip. It runs all the synchronous elements in design, and is running all the time. It consumes about 30% of chip power, so it's important to design it efficiently.

In an ideal world, we want clk to all the sequential elements to reach at the same time. That's called an ideal clock. However, in reality, clock needs to go thru multiple drivers before reaching the seq flops, and we need multiple drivers to drive 1000's of flops on chip. The goal of any clock design is to meet setup and hold timing for all paths, with minimal use of logic gates. There are 2 strategies for designing clock:

1. clock tree: In this kind of design, clk is built as a tree. So, we start with clk originating point in the center of chip, and then make branches and sub branches (as in a tree). The delay from clk starting point to final clk endpoint which drives the flop, has to be the same for all diff flops on chip, in order to get as close to an ideal clk. The difference in timing b/w different end points of clk is called skew. Ideally we want 0 skew. By minimizing skew, we can make clks as ideal as possible, and that requires fewer gates to fix setup/hold violations in paths. This design is the one that is used in most of the chips and SOCs being built today, as these consume low power.

2. clock mesh: In this kind of design, clk is still built as tree, but the leaf driver of each branch is then connected to other leaf drivers thru a mesh of wires. This mesh is similar to power grid where you have X and Y wires running in different layers. Here there is additional clock mesh connecting all final driver output. The advantage of this scheme is that now the skew is minimized even further, since 2 leaf drivers o/p are connected, so they will rise/fall at same time. The only little skew comes from this final clk point which is input port to the module to the final clk load being driven inside the module. However, this huge skew minimizations comes at large power cost, since now we have a large grid that is being driven by clk drivers all the time. For very high speed designs (i.e couple of GHz clk speed), clock mesh is preferred. Clock mesh is still used in multi GHz processor design at Intel/AMD.

 

Clk tree design:

First Question is => on which nets to build clk tree? For this, we use 2 SDC cmds => create_clock and create_generated_clock. Those are used as root points and clks starting from those point on are treated as clks, until they hit a sink point 9i.e clk pin of flop). For generated clk, the path is traced backward to the master clk, and all such possible paths are treated as clk trees.

Below are few rules which are adhered to in building clk tree:

1. Cells used for clk tree are specifically designed to be used for clk tree, i.e you can't use regular inverters and buffers used in design for clk tree as they may not have same rise/fall time, or they may not be designed for continuous switching, etc. These clk cells are usually called CK* (i.e CLKBUF, CKINV, etc). These clk cells have lots of vias in their layout to have better current flow, and also to mitigate IR drop and to have low Electromigration effect.

2. Clk tree cells should be of same VT type, i.e if using LVT cells, use LVT for all cells on clk tree. Different VT types don't track each other well (i.e their coorelation may not be good), so clk tree built using diff VT types may not show up real silicon variations in simulations, resulting in broken chip. Usually LVT cells used on clk tree for good clk slew (see bullet 7 below).

3. For very high freq clks, we use even more special clk cells which have inbuilt DeCap (Decoupling Capacitor) on supply lines to reduce Voltage variations on these cells. These cells are usually named DCCK*, and are used for clks > 1GHz freq.

4. Mix of buffers and inverters is not recommended on clk tree. This is again due to the fact that buffers and inverters may not track each other at different PVT corners. Usually only inverters used.

5. All clk routes should be shielded so that they don't get any cross talk or noise from neighboring routes. Shielding is provided by running VDD or VSS lines parallel to these clk routed lines. Also clk routes are made thicker (double wide), so that their resistance and process variation is low. Places where it's not possible to have VDD/VSS lines, metal fills should be used, so that we have uniform clk skew for all clk routes. Also lots of vias should be used on clk routes to mitigate IR drop and have low Electro Migration (EM) effect.

6. Clk routes should be placed under chip bumps. This is because a lot of current flows thru the chip bumps, and it can cause noise on these clk routes, resulting in un accounted delay or crosstalk. Cross talk on clk nets shouldn't exceed a certain threshold, usually 24%.

7. Clk slew (rise or fall transition time) should be low, so that we have crisp edges for clk waveforms. Usually we try to keep slew to be less than 1/10 of cycle time. this requires having large drivers with low fanout on the output of drivers. We still try to get to as large of a fanout as possible without degrading the slew rate too much. In the past for tech > 90nm, HVT cells were used exclusively as clk cells. They provided good enough slew rate and were less leaky. As tech progressed towards < 3nm, these HVT cells started getting replaced by LVT and eventually by ULVT cells. Reason is that power supply voltage are dropping to < 0.5V for low nm tech, and HVT cells don't have very crisp slew rate due to very low voltage headroom (Vgs - Vth). Here, LVT cells are more commonly used on clk tree path. Even though they may be more leaky than High VT cells, the provide crisp edges at these low voltages. If we use High VT. then we may have to provide more buffers to maintain crisp edge edge. This may eventually cause High VT to consume more dynamic power than Low VT cells, even though they leak less. In clock tree path, we are more concerned about dynamic power than leakage power, since cells on clock tree are switching most of the times. So, LVT or ULVT cells are OK to use to clk cells. 

Clock uncertainty:

Clock period is usually defined as a fixed number, let's say period=100MHz or period=10ns. However, if you look at 1000's of such successive clk waveforms, not each clk waveform period will be exactly 10ns. Some will be 9.9ns, while some may be 10.1ns and so on. You can view clk period as a gaussian curve whose mean is at 10ns, but sigma is around 0.1ns or so. The middle edge of the clk (i.e half period of the clk) also has uncertainty, just like the other edges. This variation from clock to clock edges across millions of clk cycles is called clk uncertainty. It can be from rise to rise edge (for full cycle) or rise to fall edge (for half cycle) or vice-versa. Uncertainty in middle edge of clk hurts more, since those are mostly half cycle paths (which have half the time to meet timing) and accounting for uncertainty leaves us with even less time to meet timing for that path. We have to account for this uncertainty in our timing runs, as worst case setup timing must now be smallest clk waveform that can be formed with these uncertainties. There is no way that any timing tool has any knowledge of such clk deviation as it assumes ideal clk coming in that we specify the freq for.

There are several sources of clk uncertainty:

1. jitter: jitter is the moving of clk edge due to clk generator ckt, noise, power supply variations, temperature variations, interference from nearby ckt, etc. It's the main component of clk uncertainty, and most of the times, people refer to jitter and clk uncertainty as the same thing. However, jitter is not the only component of clk uncertainty, though it's the major one. jitter is usually found from sims and may be expressed as Δt per mv of power supply variation.

There's a short article on various clk jitter terms here: https://vlsi.pro/clock-jitter/

RMS jitter: average value of of clock period deviation over the selected number of cycles (usually a very large number of cycles are considered)

Peak to peak jitter: difference between maximum deviation & minimum deviation within the selected number of cycles (usually a very large number of cycles are considered)

Above jitter values are calculated over all clock cycles, i.e the 1st clock cycle or the 1000th clock cycle. This is known as the clock period jitter and is the most common way of reporting jitter. Sometimes we are also interested in the cycle to cycle jitter, which is the deviation in cycle of of two adjacent clock cycles over a random number of clock cycles (usually a very large number of cycles are considered). This jitter value can be calculated for both RMS jitter or Peak to peak jitter. This value is useful in DDR and other very fast GHz clks.

Total jitter includes two components:

  • Bounded (or deterministic) jitter (DJ) => Deterministic jitter is a predictable and repeatable behavior which can be expressed as a peak-to-peak value. Deterministic jitter can be of 2 types:
    • data dependent jitter => It's correlated to the data stream. There are 2 types of data dependent jitter:
      • duty-cycle dependent jitter (also known as duty-cycle distortion or DCD) =>
      • Inter Symbol Interference (ISI) =>
    • bounded uncorrelated jitter (BUJ) => It's uncorrelated to the data stream. It's least understood in jitter family. It is considered “uncorrelated” since it’s statistically not possible to correlate it with other parts of the system. BUJ is caused by system phenomena, though. An example of BUJ would be noise inside a chip caused by sources external to the chip, be it power-rail ripple or RF interference. A number of tools are available to help model crosstalk and identify aggressor signals, but causes of BUJ are generally outside of the designer’s control.
    • Periodic jitter (PJ) =>
  • Unbounded (or random) jitter (RJ) => Random jitter is the unbounded jitter part of Total jitter, usually expressed as Rms value. It's not expressed as peak to peak value, as peak to peak is unbounded (can be infinite). It is mainly caused by unpredictible thermal noise, flicker noise or shot noise. These are all studied in device physics. Random jitter typically follows a normal distribution (gaussian curve). Since Total jitter plot of any clock shows a gaussian distribution, that implies that RJ is the main component of total jitter.

NOTE: Jitter is due to variations occurring due to different time of the edges, i.e starting edge of clk may see a different voltage, temperature, etc than the next edge of clk. So, this will cause jitter and will need to be accounted for in timing runs, since now the full cycle cycle may not be available for the paths due to jitter component. So, all full cycle setup timing runs need to consider this jitter in the clk path since the launch and capture are 2 different edges. However, full cycle hold timing runs don't consider this jitter, since both the launch and capture clk are on same edge and occur at almost same time. However, if one of the launch or capture clk is too much skewed wrt the other capture or launch path so that they are shifted in time too much, then we'll need to consider jitter in hold path too. In timing tools, we can specify clk certainty for both setup and hold (usually jitter component is removed from hold clk uncertainty). However, jitter is considered for both setup and hold for half cycle paths, since they are time shifted.

When we calculate jitter for a clock path, we separate it out in 2 components:

  1. Source jitter: This is the jitter coming from PLL or clk source. For a 24MHz oscillator, it may be something like 3ps/mV. PLL may add it's own jitter to this clk. So, for a PLL clk with freq of 1GHz, jitter may be 25ps (which is 2.5% of 1ns cycle time).
  2. Network jitter: This jitter is extra jitter added in clock network, where the clk is getting routed. This jitter is caused due to clk network supply voltage and temperature fluctuations. 5% power supply noise very common on chips with < 1V power supply, and having varying IR drops. This can easily cause jitter of 50ps or so.

Total jitter = √ (jitterpll2 + jitterstage12 + jitterstage22 + ... jitterstageN2) where N is the number of stages in clk tree. jitter per stage is usually provided in a tabular form from running sims, and may be 5ps/stage or something like that. So, more the number of stages in clk tree, more the jitter.

2. DCD (duty cycle distortion): This is applicable for half cycle paths only, so DCD doesn't contribute anything for full cycle paths. As mentioned above, DCD is actually "data dependednt deterministic jitter". This also has 2 components:

  1. Source DCD: This is the DCD coming from PLL or clk source
  2. Network DCD: This DCD is extra DCD added in clock network, due to clk network supply voltage and temperature fluctuations. Network structural (mean) and variation (sigma) DCD are now handled natively in timing tools as PrimeTime.

3. Convergence uncertainties: These are NOT real uncertainty caused by devices. Here we model some other effect of clock as uncertainty, when we do not know the impact of such effect. As an ex, consider Synthesis stage of design, where we are optimizing circuit. In synthesis stage, clock tree is assumed to be ideal (as clock tree is not built during synthesis, but during PnR stage). However, we do know that there we will be some skew b/w different end points of clk. To model this skew, we set clk uncertainty equal to an educated guess for skew. That way, the logic gets optimized with that clk uncertainty, so that later in PnR stage, we do not get too many timing violations due to skew. So, here we modeled skew as "clk uncertainty", even though it's not a component of clk uncertainty. In PnR stage, the real skew gets added for each and every path, so there is no need to add this skew as clk uncertainty in that stage. Similarly clk ocv (on chip variation) and clk xtalk (cross talk) are also modeled as clk uncertainty during synthesis stage, so that sythesis stage sees clk uncertainty as close as possible to what will be seen after CTS build in PnR stage.

NOTE: clk uncertainty may be different for different clocks, depending on their PLL source, network and other effects unique to each clk.

Derate: There may still be unaccounted jitter and DCD in clk path. To model for this, we add a derating factor, which basically worsens jitter and DCD by a given percentage. This provides us extra margin in simulations, incase silicon shows extra jitter and DCD than what sims showed.

set_clock_uncertainty: All of the clock uncertainty above are summed up and provided as a single number to the timing tool via "set_clock_uncertainty" cmd. More details on this cmd are in "PT- clock command" section.

 

Clock Tree construction:

Clock tree construction is done during the backend PnR stage. It's not done during synthesis, as we assume ideal clk during synthesis. It's done during PnR, as clk tree construction needs placement information of all cells, to come up with optimal clk tree. Clk tree construction is also called CTS (Clk Tree Synthesis). Imp parameters for any clk tree are jitter, DCD, slew and skew.

We'll look at CTS in more detail under PnR section.

 


 

Housing in USA:

This section deals with housing in USA, whether you are renting or live in your owned house. It deals with all housing issues: buying, selling, renting, mortgage, utility bills,  etc. But before we get in the details, let's take a look at some basic housing stats in USA. Just like all other USA stats, housing stats before 1980 are useless, as gold standard was abolished in early 1980, which allowed government to print infinite money. This ability to print and dump infinite money in markets, allowed assets to be priced differently. Housing is no different.

Basic housing stats from year 2018:

There are 132 Million housing units (house, apartment, or any separate living quarter), which is 20% more than the number of households (which is 112M as shown in basic facts section). As per 2009 AHS survey on HUD website, There are 130 Million residential housing units in the U.S.of which only 86 percent are occupied.

That implies 112 Million units were occupied, which matches closely to the number of households. Of these 112M occupied units, 76M were owner occupied and 36M were rented. Of the remaining 19M that were not occupied, 5M were for rent/sale (of these 1M were already rented or sold, but no one had moved in yet), 2M were for sale only, 5M were seasonal homes and 7M were others (foreclosures, etc). So, in essence, most of these vacant housing units are the ones that are in flux, where someone has moved out or is going to move in.

Of 132M housing units, 83M units are single detached houses, 7M are attached houses (as townhomes), 9M are condo, 1M are co-ops, 9M are manufactured or mobile homes, and remaining 23M are apartments. Since 36M units are rented, that implies about 13M units rented are houses rented by individuals.

So, there's a glut of 4M units (5M that were up for rental or sale minus 1M that were already rented or sold) that need rentals but there are no renters available, as everyone has a unit occupied !!! That's reasonable, since some % of population is always moving, so there will always be vacant houses at a given time. Since apartments try to remain close to 90% occupancy, they have about 2.5M units for rent with remaining 1.5M available from individuals as houses, condo, etc. Looked in other way, out of 40 million units looking for renters, only 36M were rented, which implies 90% occupancy rate. What that implies is that if you were to rent your house, count on it being occupied only 90% of the time.

A very detailed list of housing units can be found here at AHS: http://www.census.gov/housing/ahs/data/ahs2009.html

Table 1-1 gives the most basic information.

House sales: There are about 110M housing units which are not apartments. These are owned by individuals, and go on sale or rent. About 5M homes sell in a year, of which 4M are existing single family homes, 0.5M are existing condo, townhome, co-op, and remaining 0.5M are new homes. This implies that 5% of the households buy or sell house every year, with 0.5% new buyers entering the housing market every year. Since population increases by 1M households every year, 0.5M buy new houses, while 0.5M get into apartments. Since 1959, there have been more than 1M new house construction every year ( https://www.census.gov/construction/nrc/pdf/bpann.pdf ). This includes stand alone houses, condos/townhomes as well as rental apartments (with each unit of rental apartment counting as 1 housing unit). Also, new apartment units have averaged about 0.2M per year, but since 2016, they have crossed 0.3M per year ( https://www.rentcafe.com/blog/rental-market/us-apartment-construction-at-a-20-year-high-in-2017/ ). This implies that 2017 onwards, there are about 0.9M new house/condo/townhomes + 0.35M apt built every year, while household are increasing by only 1M per year, leaving a glut of 0.3M new residential units every year, on top of 4M housing glut that was already there from 2009.

One data that you will usually see in news is "new housing starts" and "new home sales" in monthly reports. One data that will stand out is that "new housing starts" are always 2 times or more of the "new home sales". You would expect both of them to be roughly the same. Reason for this discrepancy is that "new housing starts" include all construction = stand alone home/condo/townhome/rental apt, etc, while "new home sales" are recorded only for stand alone 1 unit homes. As you can see from link above, for 2017, there were 0.9M house/condo/townhome, and 0.35M apt. What we care about is the "new housing starts" as that is the number that is going to absorb the population growth.

Since 1959, 78M housing units have been built, while number of households increased from 50M to 125M. So, increase in housing units have been pretty much in line with increase in households. But as population increase slows down, either more people living separately are needed, or more immigrants are needed to consume glut of housing supply. Again, immigrants and divorces come to the rescue of housing

house price since 1991 is available at this link (based on mortgage purchase price): https://www.fhfa.gov/DataTools/Downloads/Pages/House-Price-Index-Datasets.aspx#mpo

One of these links here gives housing data for top 100 metroploitan areas since 1991: https://www.fhfa.gov/DataTools/Downloads/Documents/HPI/HPI_PO_metro.txt

There is a graph for 100 years of housing prices: http://observationsandnotes.blogspot.com/2011/06/us-housing-prices-since-1900.html

Other housing price data: https://dqydj.com/historical-home-prices/

If you see data for USA, you will notice that prices doubled in 24 years from 1991 to 2013, implying 3% annual appreciation. Looking at 100 years of data, we again see the same trend. House prices had 3% appreciation while avg inflation was also 3%. So, house prices remained the same over 100 years when accounted for inflation. This is because, cost of everything related to building house (labour, material, land, etc) goes at the same rate as inflation. However, since 2012 house prices have started appreciating much faster than inflation. If house prices double every 10 years, that implies 7% annual appreciation. Assuming mortgage rates are 5%, property taxes + insurance of about 2%, that implies that you are living in the house for free, since all your house expenses are paid for by appreciation of the house. So, once you buy a house, you have entitled yourself and your future generations for free rental as long as sun exists. Assuming, you never pay off your mortgage (keep on refinancing it every 5 years to next 30 years). This also means that you can buy a property financed 100% with a loan, rent it for free, and still not lose money, since price appreciation will make you whole.

 


 

Home Prices Vs GDP:

To the first order, GDP is a measure of total amount of money circulating in the system. It makes sense that home prices will follow the GDP. IF we look at GDP and home prices over last 75 years, we can see a correlation. Below is the graph for median home prices:

https://fred.stlouisfed.org/series/MSPUS

We'll assume 40M houses (excluding apartments) for year 1950, and add 1M houses every year. GDP stood at $300B in 1950, while median home prices were about $18K. Assuming 40M houses with avg price of $18K, total housing value was 40M*$18K=$720B in 1950 which is about 2.5X of GDP.

By 1980, GDP went up 10X to $3T, while median home prices rose 3X to $60K. Assuming 70M houses and median price of $65K, that gives total housing valuation of $4.5T, which is 1.5X of GDP. In these 30 years, GDP increased much faster than home prices. Fast forward to 2007 (before the big recession), GDP was $15T (5X increase), while median prices were $260K (4X increase), implying total housing worth = 110M*$220K=$25T, which is about 1.6X of GDP. As of 2022, GDP=$26T (1.6X increase), while median home prices are almost $500K (2.2X increase). Assuming 120M houses, that total housing worth = 120M*500K = $60T. I read in an article that total US housing was worth $50T. Either way, housing market is 2X the GDP.

In the years starting from 2000, home prices increased faster than GDP. GDP went from $10T to $25T (2.5X), while median home prices went from $170K to $480K (2.8X). In the years since the pandemic of 2020, home prices accelerated much faster than GDP. GDP went from $20T to $25T (25% increase),while median home prices surged from $320K to $480K (50% increase) from 2019 to 2022.

 


 

Home Prices Vs Mortgage Loans:

Based on 2024 report, Home equity of US homeowners stood at record high of $32T as of 1st qtr of 2024.

CNBC: https://www.cnbc.com/2024/09/11/home-equity-is-at-a-record-high-heres-how-to-tap-it.html

Based on stats here: https://www.lendingtree.com/home/mortgage/u-s-mortgage-market-statistics/

  • There are 84M Mortgages in USA

 


 


 

javascript (JS):

Now that you learned DOM basics, javascript is easier to learn as DOM and javascript kind of go together.

This is one of the best tutorials on javascript on digitalocean website: https://www.digitalocean.com/community/tutorial_series/how-to-code-in-javascript

javascript or JS is one of the core languages besides HTML and CSS that go into your website. Supoort for javascript is built into the browser, so that no extra plugin is required to run javascript. Javascript runs locally on your computer, by browser downloading the script from specified location and then running locally. Javascript makes web pages interactive, and so has become very popular (as HTML, CSS just provide static webpages and were never designed for dynamic interaction).

console: In DOM section, we saw how to open console in firefox, and write javascript cmds on it. This is also called "javascript console".This console is like javascript shell, where we can try any javascript cmd in real time.

console.log() => To o/p anyhting on this console, we can use console cmd below. This console cmd is useful during debug of javascript to dump out values.

>> console.log("Hello") => This will print "Hello" on javascript console

>> console.log(4+5); => This will print "9" on console.

alert(): This is another function used to print values in a pop up box. This is also used to dump out values.

>> alert("hello") => brings a pop up box with "hello" written on it.

Adding JS into HTML doc:

JS is added into HTML doc by adding tag <script> ... </script>. Just as in CSS, they can be inserted inline or as a separate file. Generally JS is put into the <HEAD> section, signalling the browser to run the JavaScript script before loading in the rest of the page. However, if your script needs to run at a certain point within a page’s layout, then it has to put at a point, where it is to be called, generally in <BODY> section. Putting JS in HEAD section is preferred, as it keeps JS separate from main HTML content, but it's not always possible.

1. Inline: Here, JS code is put directly within <script> tags. In ex below, JS function alert( ) is called in <head> section, so a popup with msg "Hello" shows up on browser, even before the erest of the page loads. This is because <body> section hasn't even run yet, as alert ( ) is in <head> section.

<head>

  <script>

    alert("Hello")

  </script>

</head>

2. separate file: Here, JS code is put in a separate file, so that it's cleaner. In ex below, test.js is a separate JS file having JS function alert("Hello");

<head>

  <script> src="/test.js"  </script>

</head>

Syntax: Just like any other programming languages, JS also has variables, reserved keywords (if, else, etc) and special characters (for doing arithmetic, signalling end of cmd, etc).

1. Whitespace: Whitespace in JavaScript consists of spaces, tabs, and newlines. Whitespace is used to separate out tokens. Extra whitespace is ignored. Some tokens may be recognized even without whitespace, however, it's preferred to put whitespace.

2. semicolon: JS consists of multiple statements. Each statement is terminated by a newline or a semicolon( ; ). semicolon is mandatory when there are multiple statements on a single line. It's possible to write entire JS program in a single line by using semicolons and spaces, but that would be unreadable. Indentation (or using multiple spaces) is good way to make your pgm readable.

ex: alert("Me"); var a="ASD";

3. comments: JS comments are written in same style as in C language. single lines comments are written using //, and multiline comments within /* this is multi line comment */

4. variables / identifiers: The name of a variable, function, or property is known as an identifier in JavaScript. Identifiers consist of letters and numbers, but they cannot include any symbol outside of $ and _, and cannot begin with a number. They are case sensitive. They are declared using "var", "let" or "const". Initially JS only allowed keyword "var" to declare variables, but now 2 additional keywords "let" and "const" used. That is why in lot of legacy JS code, only "var" is seen. However it's recommended to use "let" and "const" instead of var. "let" is used for variables that can be reassigned as in loops, etc, while "const" is used everywhere else, where var are fixed and never modified or reassigned. The scope of variables may be local or global (i.e if variables may or may no be accessible outside the function or block where they are defined). The scope of "let" is block level, while scope of "const" is global level. See digitalocean link for more details.

 var myname = "Tom". Here myname is an identifier which stores var "Tom" which is of string type.

let tr=23;

const Me="Ajay";

let ToVar; => We can also define a var, but not initialize it to any value. Then we can assign it later as ToVar=1;

Data Types: variables can be of different data types. In JS, just as in other scripting languages, we don't define data type beforehand. Variables can be accessed directly by their identifier (no need of appending it with any special var). These are the primitive data types in JS:

I. number: Both integers and floating point numbers can be declared. Scientific notation is also supported.

let t = 16;         // t is a number.

var t = 14.23 //t is floating number

console.log(t) => prints value of var t. ooks for a var named t and if found prints it's value. It knows t is a var, since it's not a number, not a string (since not enclosed within quotes) and not a boolean.

var t; //here t is undefined, so is assigned null value

Arithmetic operators: as+, -, *, /, +=, ++, etc can be applied on number data type.

ex: 10 +20 => returns 30

ex: let a=4.2; let b=2.1; let c=a / b; => here c is assigned 4.2/2.1=2

ex: let x=a++; ++ and -- are increment and decrement operators. Used in for loops

II. string: A string is a sequence of one or more characters (letters, numbers, symbols).  There are 3 ways to write a string: single quotes ( ' ... '), double quotes ( " ..." ) and backtick ( `.... ` ).There's no difference b/w single or double quotes. backtick quotes is the newest method and is also called template literal. It allow substitution of variables inside the quotes. "+" is a concatenation operator for strings (i.e it joins 2 strings).

ex: let t = "Mother Teresa";   // t is a string

let T='teresa' + t; //this concatenates 2 strings and assigns it to T. So T = "teresa Mother Teresa"

backtick: Above we had to use + to concatenate string, since anything inside single or double quotes is interpreted as string, so we could not have used our variable inside quotes. However, backtick allows us to do that by using ${}.

ex: let T=`teresa ${t}` => here t is seen as a var, and it's value is substituted.

NOTE: when having single or double quotes as part of string, we can use \' or \" to treat it as part of string, or use backtick to store that string (since then single or double quotes won't be recognized as end of string). Also, \n is recognized as newline in a string, or even string on different lines is recognized as same string with newlines in between (string continues as long as ending quotes are not found)

string manipulation: There are many methods available to manipulate strings. Note that string is treated as an array of characters starting with index 0.

const originalString = "How are you?"; => Here index [0]=H, [1]=o, [2]=w, [3]="space" or "blank", [4]=a and so on ....

var char5 = originalString[5] => this returns index 5 of above array of char, which is char "r".

originalString.charAt(5) => returns index 5, which is r"

"My name".indexOf("n") => return index number of char "n", which is 3

//slice of string

"How are you?".slice(8, 11); => returns "you"

originalString.sliceof(8) => returns everything starting from index 8 to end of string, so this returns "you


// Split string by whitespace character
const splitString = originalString.split(" "); => this splits string by whitespace, so var splitString is now an array [ 'How',  'are',  'you' ]

console.log(splitString); => we can now access various elements of array too, via splitString[0], etc

There are various other methods to convert cases, finding length, trim, replace, etc. These can be found in digitalocean link at top.

III. Boolean: The Boolean data type can be one of two values, either true or false.
let t = true;       // t is a Boolean

let myBool = 5 > 8; // var myBool is assigned a value "false"

IV. array: An array can hold multiple values within a single variable. square brackets used to hold elements of array. They can store any data type as number, string or objects, and single array can have mixed dat types. Arrays can contain arrays within it. Arrays are similar to string, since strings are array of characters.

ex: let fish = ["shark", "cuttlefish", "clownfish", "eel", 7, ["meen", 9], null, 0]; => declares an array of string, number, etc.

ex: fish; => this will print the contents of entire array named fish. We can access items in an array via index, i.e fish[0] refers to 1st element of array, etc.

Array methods: We can use many methods to access various elements of array, or remove/add elements, modify elements, etc.

There are 3 kinds of array methods available:

1. mutator methods: these modify the array itself (i.e adding, removing elements, etc).

Array methods are properly written out as Array.prototype.method(), as Array.prototype refers to the Array object itself.

isArray(): returns True if var is an array. ex: Array.isArray(fish) => returns boolean true

pop(): removes the last element from the end of an array.. ex: fish.pop() => removes last element 0 from fish array.

similarly other methods as push(), shift, unshift, sort, etc. Because of these methods, it's very easy to work with arrays.

 2. accessor methods: these return new value or representation. methods such as concat, slice, indexOf, etc

ex: let newfish = fish.slice(2,4); => create new array with elements from index 2 to index 3. newfish = ["clownfish", "eel"]; NOTE: last index has to be one more than the index you want. So, in this case, we did (c,4), even though we wanted (2,3).

 3. iteration methods: These are used to operate on every item in an array, one at a time. These methods are closely associated with loops. 

To access all elements of array, we can use for loop below (discussed later).

for (let i = 0; i < fish.length; i++) { //here length is a property of array, not a method
  console.log(i, fish[i]);
}

Other way using method:. This prints each element of array (same as above), but using a method forEach. Here forEach method calls a function, which we'll learn later
fish.forEach(individualFish => {
    console.log(individualFish);
})

Similarly many other methods available, as find, reduce, etc

V. objects: The JavaScript object data type can contain many values as name:value pairs. These pairs provide a useful way to store and access data, and can be of any data type. The object literal syntax is made up of name:value pairs separated by colons with curly braces on either side { }. The name value pairs are called the property of the object. We can also have methods or functions as part of object. As a data type, object is stored in variable.

2 ways to construct an object:

1. Using object literal: This is preferred method. This uses curly braces { ... }

ex: below ex creates an object var named "sammy", which contains values as indicated. We can have functions too. The whole statement can also be on same line, however that makes it unreadable.

let sammy = {
    firstName: "Sammy",
    lastName: "Shark",
    color: "blue",

    greet: function() {
        return `Hi, my name is ${this.firstName}!`; //this keyword inside an object refers to current object, in this case to "sammy"
    },
    location: "Ocean"
};

We can print object data by just typing anme of object.

ex: sammy; => prints all data

{firstName: "Sammy", lastName: "Shark", etc ....}

We can also create empty object.

ex: const sammy = { }; //cretaes empty object named "sammy"

2. Using object constructor: This is one other way to create object, by using "new" keyword

ex: const sammy = new Object();

Properties and methods:

Objects can have properties and methods as discussed above.

There are two ways to access an object’s properties.

  • Dot notation: using a dor (.): ex: sammy.firstName => returns "Sammy". Dot notation is more widely used, but has it's limitations.
  • Bracket notation: using square brackets [ ] : ex: sammy["lastName"] => "Shark". Bracket notation is used if an object’s property contains any sort of special character.

Objects's methods can be accessed the same way as we access any function, here it's just attached to the object variable.

ex: sammy.greet() => returns "Hi, my name is Sammy"

Modifying or adding to objects properties and methods is easy to do via assignment operator (=). We can use either dot notation or bracket notation.

ex: sammy.firstName = "Akbar" => this changes the value for key=firstName

We can methods by just attaching a new function to object.

ex:

sammy.hello = {
        return `Hi, my location is ${this.location}!`;
    },

Removing object's properties is done via delete cmd:

ex: delete sammy.firstName => this removes key value pair from object "sammy"

We can loop thru object's properties via "for ... in" loop. NOTE: this is different than "for ...of" loop that is used for arrays. "for ...in" loop is specifically meant for iterating over the properties of an object.

// Get keys and values of sammy properties
for (let my_key in sammy) { //my_key is a var
  console.log(my_key.toUpperCase() + ':', sammy[my_key]); //
}

Built in objects: There are many built in objects and associated methods in Javascript.

1. date: The Date object is a built-in object in JavaScript that stores the date and time. there are many methods associated with it.

ex: // Set variable to current date and time
const now = new Date();
now; // prints current date and time. returns => Wed Oct 18 2017 12:41:34 GMT+0000 (UTC)

now.getTime();// getTime is a method of Date object. Gets the current timestamp,

 

Finding data type: To find the type of any var, we can use function typeof:

ex: typeof originalString => this return string, since it's defined as string above (by enclosing it in double quotes)

ex: console.log(t) => l


let t;              // t is undefined

ex: var myNum= 1 => this assigns it to number type

ex: var a = "my world" => this assigns it to string type

Converting data type:

When using operators, JS coerces data into particular type if needed. This is implicit conversion.

ex: "3" - "2" => even though 3 and 2 are strings here, JS comverts them to number since operator "minus" works on numbers, Returns result as 1

We should always explicitly convert data type to remove ambiguity by using below methods

String(49) => converts number 49 to string "49" and returns "49"

(1776).toString() => converts number 1776 to string "1776"

let str="17";

Number(str) => converts string "17" to Number 17.

Boolean(0) => converts number to boolean, returns false

Boolean("man") => returns boolean true, as any non zero number or string is treated as true

Conditional Statements:

1. if-else: same as if else in other languages. "else" and "else if" are optional.

if (condition a) {
    // code that will execute if condition a is true
} else if (condition b) {
    // code that will execute if condition b is true
} else if (condition c) {
    // code that will execute if condition c is true
} else {
    // code that will execute if all above conditions are false
}

ternary operator: similar to ? : in C lang, it's an alternative form of if else.

ex:
let age = 20;
const oldEnough = (age >= 21) ? "enter." : "not enter.";

2. switch: same as switch case in other languages.

switch (expression) {
    case x:
        // execute case x code block
        break;
    case y:
        // execute case y code block
        break;
    default:
        // execute default code block
}

Loop statements:

1. while, do while: runs loop based on condition. if-else and switch stmt run only once, while runs in a loop as long as the condition is true.

A. while loop: If we put "true" inside while condition (i.e while (true) { ... }), then loop runs infinitely. If we put "false", then loop never runs.
while (fish < popLimit) {
    fish++;
    console.log("There's room for " + (popLimit - fish) + " more fish.");
}

B. do while loop: this loop will always execute once, even if the condition is never true.

do {
    // execute code
} while (condition);

2. for loop: 3 types of for loop: for, for .. of, for ... in

A. for loop: uses 3 optional expr that control execution of loop. All 3 expr are optional and for loop will still run. However the loop may become infinite, if there are no epr to control the loop's var value, so a break stmt inside the loop might be needed. for loops can be used to modify or read values of arrays.

ex:
for (let i = 0; i < 4; i++) {
    // Print each iteration to the console
    console.log(i);
}

B. for .. in loop: used to iterate over the properties of an object. See in object section above.o

C. for .. of loop: This is used to iterate over iterable objects like arrays and strings, The for ... of statement is a newer feature as of ECMAScript 6.  ECMAScript (or ES) is a scripting-language specification created to standardize JavaScript. We looked at the iterator method above to access all elements of an array, which used regular for loop. Here, we use the for ... of loop.

 ex: This prints all elements of array.
let sharks = [ "great white", "tiger", "hammerhead" ];

for (let shark_name of sharks) {
    console.log(shark_name);
}

 A string can be iterated through in the same way as an array (as a string is eventually an array of char).

ex: This prints each char of string

let sharkString = "sharks";
for (let shark of sharkString) {
    console.log(shark);
}

Functions:

Functions are same as in other pgm languages. Function can have optional args.

3 types of function syntax allowed:

1. Regular function defn: Here we define functions the regular way

ex:  Here we first define function "greet"  with 3 args. Args are optional. If no args, then just do "function greet( ) { ... }".
function greet(name, a, b) {
    console.log(`Hello, ${name}!`);

   return a+b; //return is optional.
}

greet("Sammy", 5, 6); // Invoke greet function with "Sammy", 5, 6 as arguments. Since function returns a value, so 5+6=11 is returned. This value is returned at the point in pgm, that this function is called. It prints 11 on screen, even though we didn't print out the value explicitly by using console.log. This return value can be used immediately or stored in a variable.

2. Function expression: Here, we  assign function to a var.

ex:
const sum = function add(x, y) { //function is named add, but the function itself is stored in var "sum"
    return x + y;
}

sum(20, 5); //Here we invoke function via the var (function name not needed)

Anonymous functions: Since function name is not really needed for anything when using the var to store the func, we can omit func name altogether. These are called anonymous functions.

ex: here function name "add" is omitted, although parenthesis and args still needed.
const sum = function(x, y) {
    return x + y;
}

sum(100, 3);

3. Arrow functions: This is a newer, more concise method of defining a function known as arrow function expressions as of ECMAScript 6.  Arrow functions are represented by "=>". Arrow functions are always anonymous functions and a type of function expression.

ex: Here we omit the word "function" and instead use arrow "=>" after the args. If there are no args, empty parenthesis needed. However, if there is only 1 arg, then parenthesis is not required.


const multiply = (x, y) => {
    return x * y;
}

multiply(30, 4);

NOTE: if the function consist of a return statement only, arrow functions allow the syntax to be reduced even further. If the function is only a single line return, both the curly brackets and the return statement can be omitted, as seen in the example below.

ex:
const square = x => x * x; //NOTE: no parenthesis or curly braces needed. No "return" keyword needed either.

square(10);

Events:

Events are are actions that take place in the browser that can be initiated by either the user or the browser itself. We learned a little bit about events in DOM. They are an integral part of javascript, as we can code responses to events in browser, that can make the page look responsive.

Most common events are:

1. mouse events: They refer to events that involve clicking buttons on the mouse or hovering and moving the mouse pointer. 

 ex: click: Fires when the mouse is pressed and released on an element

2. form events: actions that pertain to forms, such as input elements being selected or unselected, and forms being submitted.

ex: submit: Fires when a form is submitted (i.e submit button is clicked on form element)

3. keyboard events: used for handling keyboard actions, such as pressing a key, lifting a key, and holding down a key.

ex: ketpress: Fires continuously while a key is pressed

Event handlers: Whenever an event is fired (by user clicking mouse, etc), a JS function can be made to run. This function is called event handler. Button, form, etc are elements of an html page. These elements have properties or attributes such as submit, click, etc (i.e button has onclick attribute). We can assign events to these elements. 

There are three ways to assign events to elements:

  • Inline event handlers
  • Event handler properties
  • Event listeners

1. Inline event handlers: Here we set event handler on attribute of an element. Then we assign an attribute value which is the JS function that we want to call. It's called inline as we add handlers to every element that we want to respond to events. This is very cumbersome/inefficient, and so should not be used at all.
ex:   In below ex, we assign value of "onclick" (NOT onClick, i.e all small letters) attribute of button element to "changeText()" JS function. In js/test.js, we define this function to change text of p element in html.

<button onclick="changeText()">Click me</button>
<script> src="/js/test.js"  </script>

js/test.js => Below file has function defined to modify the text content of the paragraph
const changeText = () => {
    const p = document.querySelector('p');
    p.textContent = "I changed because of an inline event handler.";
}

Forms: With forms too, we can have inline event handlers. We have attribute onsubmit of a form, on which we can apply event handler.

ex: <form action ="script/action_page.php" onsubmit="ValidateForm()" .. > => Here unless the value returned by function "ValidateForm" is true, the action "script/action_page.php" won't be taken.

 2. Event handler properties: Very similar to an inline handler, except we’re setting the property of an element in JavaScript instead of the attribute in the HTML. In the above ex, we set attribute "onclick" to JS func in HTML itself, but here we set property "onclick" to JS func reference in JS code. This also should not be used, as we have better 3rd way of handling events.

ex:

<button>Click me</button> => NOTE: we didn't assign any value to onclick attribute.
<script> src="/js/test.js"  </script>

js/test.js => Now we access above element "button" in JS itself (just like we access any other element of HTML in JS), and assign JS function pointer to it's property "onclick". NOTE: onclick is a property of button element here, instead of an attribute.
const changeText = () => {
    const p = document.querySelector('p');
    p.textContent = "I changed because of an event handler property.";
}

// Add event handler as a property of the button element.
const button = document.querySelector('button');
button.onclick = changeText; => NOTE: when passing a function reference to the onclick property, we do not include parentheses, as we are not invoking the function in that moment, but only passing a reference to it.

3. Event Listeners:  An event listener watches for an event on an element. Instead of assigning the event directly to a property on the element (as in example above), we use the addEventListener() method to listen for the event.  addEventListener() takes two mandatory parameters — the event it is to be listening for, and the listener callback function.

Event listeners are the newest and preferred way to handle events. They have the advantage that multiple listeners can be added to same event and element, while with the "event handler property" method above, last property set on an element overwrites all previous properties. Furthermore, you can use addEventListener() on the document and window object too.

ex:

<button>Click me</button> => NOTE: we didn't assign any value to onclick attribute.
<script> src="/js/test.js"  </script>

js/test.js => Here, we define 2 functions, and add 2
const changeText = () => {
    const p = document.querySelector('p');

    p.textContent = "I changed because of an event listener.";
}

const alertText = () => {

alert("Am I here?");

}


//Here we access addEventListener() method of element "button". We listen for "click" event on button, and then call appr function.
const button = document.querySelector('button');
button.addEventListener('click', changeText);

button.addEventListener('click', alertText);

// An anonymous function can also be added on an event listener. Anonymous functions are functions that are not named. Often, anonymous functions are used instead of a function reference on an event listener. 
button.addEventListener('click', () => { //NOTE: no separate func called, but func body defined here itself.
    p.textContent = "Will I change?";
});

NOTE: With the first two methods, a click event was referred to as onclick, but with event listeners it is referred to as click. Every event listener drops the on from the word. 

 

Event Objects: We talked about various events earlier. These events can be accessed via objects. The Event object consists of properties and methods that all events can access. In addition to the generic Event object, each type of event has its own extensions, such as KeyboardEvent and MouseEvent.

The Event object is passed through a listener function as a parameter. It is usually written as event or e. We can access the code property of the keydown event to replicate the keyboard controls of a PC game.

ex: Access the code property of "keydown" event. "keydown" event is captured in "event" object. We then access the "code" property of that event.
document.addEventListener('keydown', event => {
    console.log('code: ' + event.code); //This returns the key pressed, as "KeyA", "KeyB", etc
});