Report of frontend internship at Housing.com
Frontend Development in Housing.com
Ravi Kachhadiya
Dhirubhai Ambani Institute of Information and Communication Technology,-On-Campus Mentor: Prof. Jaideep Mulherkar
On-Site Supervisor: Mr. Sukhdeep Singh Handa
Elara Group (Housing, PropTiger and Makaan), Gurugram
Abstract—Housing.com is one of the fastest growing real-estate
platforms facilitating home-seekers to find their dream home. The
platform has stood out amongst its competitors and its technology
team has been the backbone of its growth over the years. Finding
unique and innovative solutions to novel problems is imbibed in
the spirit of the team. As an intern I feel privileged to be part of
this organization and contribute my part. I’ll try expressing my
journey in the company in terms of learnings, my contributions
and how the frontend technology is pushing its boundaries since
the last decade and the way Housing.com has leveraged on it.
Index Terms—React, Redux, Lazy Loading, APIs, Suspense,
SEO, Q&A
I. L EARNING P ERIOD
A series of training sessions were planned for 2 weeks for
frontend interns. A brief description of them is as follows:
1) Web Fundamentals - which included history of the web,
request/response cycle, understanding the functions of
clients, servers and HTTP Protocol, synchronous and
asynchronous requests and working of the browser.
2) HTML, CSS - The former being the raw markup of
the content displayed on a webpage and latter being
responsible for the positioning and styling. Advanced
CSS layouts like flexbox and grid was covered.
3) Javascript - The language that is working behind the
beautiful animations and complex interactions, so easy
to pick up yet takes years to master. Basics like
datatypes, functions, arrays, objects, single threaded,
asynchronous concepts were covered.
4) DOM APIs - How all the browsers quickly adopted to
the rise of Javascript and exposed functionalities that
allowed developers to interact with DOM elements.
5) Advanced Javascript - OOP’s concepts, Prototypes and
Closures, how Javascript inculcated OOPs paradigms
which caused Java, C# programmers lives difficult who
got in touch with Javascript.
6) Javascript new Features - Modules(CJS, ESM, AMD)
when gone were the days when developers used
javascript for small scripts and a bit of interactivity. The
new era of entire web applications running on browser
with tons of javascript code began. Callbacks, Promises,
generators, async/await were introduced against never
ending needs of developers enabling them to achieve
doing different things efficiently.
7) Node - which facilitated javascript to even run on
servers. It became instantly popular and tons of libraries
were built on top by the community, most famous being
the Express providing a minimalist approach towards
creating a web server.
8) React - the most popular UI framework present that
facilitated creating complex UI interfaces by breaking
them into reusable UI components.
9) Redux - A predictable state container for apps.
10) Graphql - A data query language born out of Facebook’s
increasing concern for native mobile applications a
decade ago.
Numerous 1-day assignments like creating a static html
page from https://onepagelove.com/templates/html-templates,
creating advanced calculator and creating two list and supporting CRUD operations on items and drag and drop items
from one list to another. These assignments helped getting the
fundamentals strong in the vast ecosystem.
II. H OME AUTOMATION M INI P ROJECT
After the conclusion of the training period, a mini project
on Home Automation was asked to build within a week as
part of evaluation. The final application I had delivered at the
end of a week looks as shown in figure 1. Modal that opens
on click of Add Room button is shown in figure 2.
Fig. 1. Home Automation
•
•
Fig. 2. Add Room
Key implementation notes(based on requirements):
• Implemented with only javascript and Node(No react/redux)
• Persistent data system, Mongodb NoSQL database used
for storing information on the backend.
• App reflects the updated state on reload.
• User can add new rooms with their choice of items.
• State of UI is consistent with the backend.
Code Patterns learnt during implementation:
• Importance of modularity: Writing the entire javascript
code in a single file is one of the most important mistakes
beginner programmer learns from. It doesn’t hurt until
bugs start surfacing and debugging becomes nightmare.
• Reusability: The idea of reusing the same piece of code
to render multiple instances of items( Rooms, Lights,
Heater) with different data is novel and refreshing for
someone who isn’t familiar to UI frameworks. Javascript
classes came to my rescue. It was difficult to think in
object oriented paradigm and took some time.
Listing 1: Light Class
export class Light{
constructor(light){
const{_id, state,name} = light;
// Object initialization
}
deleteItemHandler(){
// deleting light object.
}
lightHandler(){
//toggling state of light
}
render(items){
//returns DOM node for light
// and attaches event listeners
}
}
Every light, heater, room object maintained its own state
and had handler methods to respond to events(such as
click) that changed its state(from on to off or vice versa)
which in turn changed the UI view.
HTTP Methods for RESTful APIs: HTTP GET method
used to fetch data(representation in JSON) for all rooms
on initial load. HTTP POST methods used to toggle item
state or adding a room, the request body of HTTP request
containing the data.
NoSQL database: MongoDB is one of the document
databases that stores documents(similar to JSON Objects)
forming collection of pairs of properties and values. It
is so strikingly simple to represent the data model of
UI in mongodb as documents. Mongoose is a layer of
abstraction over MongoDB that can help enforce schema
of documents present in MongoDB database. Operations
consisting of updating and creating documents must reference the schema.
Listing 2: Room Schema in Mongoose
new mongoose.Schema({
name:{
type:String,
required:true
},
items:[
{
id:{
type:String,
required:true
},
type:{
type:String,
required:true
}
}
]
})
Here the data representation of object instances of Room
Class in frontend is so tightly coupled with representation
of documents enforcing Room Schema in backend. This
might be obvious, but the mental model becomes quite
easy when working with MongoDB on small-medium
sized projects and as a result correctness of code increases. MongoDB is no-doubt marked as the world’s
most popular NoSQL database.
III. P LATFORM G ROWTH T EAM
After little more than a month into internship, I was included in Platform Growth squad and was ready to take next
challenge. The experience of being part of agile organizations
consisting of small squads which are functioning like startups of their own is quite empowering. Folks from marketing,
frontend developers, backend developers and a product owner
form a self-managed and self-sufficient team that is capable
of finishing huge user stories within a sprint itself. Product
owner owns reponsibility of feeding user stories to the team
on per sprint basis.
Platform Growth Team’s main vision is SEO performance,
simply put to rank our website higher in google SERP(Search
Results Page) and as a result increase the organic traffic. To
achieve the objective, it is essential that our website is accessible for bots to read. Several factors like unique descriptions
and titles, fast-loading web pages, well formatted URLs, optimized images, meaningful structure of page(Header, Breadcrumbs, Footer etc.) contribute to make Housing.com a SEO
friendly website.
IV. Q&A M ODERATOR PANEL OVERVIEW
Q&A is biggest source of UGC(User Generated Content).Idea is to leverage the Q&A section for SEO, as well
as, to improve the user experience by solving the product
flaws received from questions. Q&A section is best suitable for
products which have repeat use-case, for example - Projects,
Localities, PGs, Brokers, and Builders. This section can’t be
used for rental and resale properties.
Q&A Moderator Panel has been one of my primary work
done in internship. Q&A Moderator Panel is an internal panel
used to moderate the questions asked on Q&A section on
PDP(Project Dedicated Pages)as shown in Figure 3. It is must
have requirement so that questions can be approved or rejected
and also answered by the moderator to scrutinize the platform.
Moderator’s responsibilities include to:
• Reject questions that use profane or obscene, inflammatory or spiteful wordings or those questions that abuse,
denigrate or threaten other (builder/developer).
• Reject questions that are personal opinion and are not intended to get additional information or provide additional
information to other users. Such questions will be posted
on IREF(Indian Real Estate Forum).
• Reject questions which are already asked or answered.
• Reject questions that promotes illegal or immoral conduct
or Repeated posts that make the same point excessively or
any form of "spam," including advertisements, contests,
or other solicitations for other websites or companies; or
any URL link that includes a "referrer" tag or affiliate
code.
• Answer the questions.
V. D IFFERENT PAGES , I MPLEMENTATION AND C ODE
PATTERNS
Every page in moderator panel follows a 3 column-layout
structure, wherein the leftmost column is the navigation bar,
middle one is for content and the rightmost is for moderation
guidelines or project details. Questions are categorized on
basis of unanswered, answered and rejected in navigation bar.
As seen in Figure 4, Home Page gives statistical overview of
all 3 categories of question on a timeline.
• Concept of code-splitting and Lazy Loading: Codesplitting and lazy loading are one of the strategies to
Fig. 3. Q&A Section on PDP
Fig. 4. Home Page
decrease the bundle size. There was a time when the
websites weren’t javascript heavy and mostly relied on
couple of js files to be requested by browser. The modern
web applications include thousands of javascript files. It
would take eternity to request all of these individually. As
a result, bundling came into picture and it is the process of
following imported files and merging them into a single
file: a “bundle”. [1] The idea of loading the entire web
app on one go(as a bundle) was great and this gave birth
to SPAs(Single Page Application). After bundle is loaded,
javascript takes care of interactions, network requests and
routes.
As the size of the application grows, the bundle grows
too. Inclusion of third party libraries can significantly
increase bundle size and as a result application takes a
long time to load. Bundlers like WebPack offer support
for code-splitting which can create multiple bundles of
code that can be dynamically loaded at runtime. The
performance of the app can increase many folds if code
is splitted into bundles thus enabling lazy loading of
•
things that are currently needed by the user. In short,
code splitting is idea of breaking your app into various
parts so entire app does not load straight away.
Lazy loading implementation: Lazy loading enables splitting by route, where the required bundles are only requested when a user attempts to navigate to a given route.
For example if user is currently at home page, then code
of other routes; for instance
interface(component) on ’/unanswered’ route should not
be loaded along with interface. We need a way
to tell React that interface is not
necessary when a user visits our site, therefore we want
to split that away from the main bundle. React Standard
Library offers React.Lazy and Suspense as a way to
achieve lazy loading. Lazy is simply a function and takes
a function as an argument which must return a dynamic
import. Function inside import uses arrow function syntax
which can referred here [2]
// This is only a snippet to showcase the idea.
import React, {Suspense} from ’react’;
import { BrowserRouter as Router, Switch,
Redirect, Route } from ’react-router-dom’
//import Home from ’pages/Home/index.js’ Standard
import statement with no code-splitting.
const Home = React.lazy(() =>
import(’pages/Home/index.js’) )
)
Fig. 5. Guidelines
React features without writing a class), React.Lazy Api
and Suspense(for code-splitting). These changes became
instantly popular so much so that React codebases around
the world started refactoring to incorporate new features
within no time.
Redux is one of the most popular Javascript library state
management. Application state is like a global object that
holds information. Components connect to the store and
retreive the data used for rendering. Initial state of Q&A
moderator panel looks along these lines:
{
cookies:{...},
masterTags: ["price", "location","legal
Approvals", "amenities", "home loans", ...]
filters:{
unanswered:{}
answered:{tags:["home loans", "location",
"possession"]},
rejected:{}
},
data:{
unanswered:[{
questionTitle: ’price of 2 bhk’,
tags: ["price"],
createdBy:{},
...
},
...],
answered: [...],
rejected: [...]
}
const QuestionPageWrapper = React.lazy(() =>
import(’pages/MainWrapper/index.js’) )
)
export default function Routes () =>{
return(
Interface loading...
}>
)
}
•
Lazy is a simple api for importing components via code
splitting. We need a way to display them if fully loaded
and display some fallback placeholder if they are not.
That’s where comes into play. Wrapping the
lazily imported Component with Object does
the job. used in above snippet looks through its
children s and renders the first one that matches
the current URL.
One more example of lazy loading is the Guidelines
modal(Figure 5) which can be opened by clicking on
View all Guidelines present on Home page(Figure 4).
Here the Modal interface is lazy-loaded.
React, Redux: Annual React Conference conducted in
2018 introduced hooks(That lets us use state and other
}
There are 2 important patterns Redux follows; first being
Single Source of Truth and second being Immutability.
Single source of truth means one app - one store - one
state. Important thing to note here is that the components
in React can contain their own internal state also. Putting
everything in application state normally is not at all a
good idea. Immutability means we can’t modify the state
object and its properties directly. Instead, we make a new
object, recalculating new application state and updating
with newly created object; leaving the old state object
intact. A thorough explanation of immutable data in
Redux can be found here [3]
Another important part is data fetching logic. React provides useEffect Hooks to perform side effects in function
components. [4]. Unanswered question page is shown in
Figure 6. Tags present on the question can be edited.
These tags are also present on filters as shown in Figure
7.
Fig. 6. Edit Tags
is rendered for routes of ’/unanswered’, ’/answered’ or
’/rejected’. Without diving too deep into the syntax of
below code snippet, we can understand that useEffect is
basically run only once after the component is initially
rendered. It simply calls fetchMasterTags() and fetchAllQuestions(), which recursively calls the corresponding
apis. Once the data is fetched from API, it should be
updated in the store(global application state). We assume
that it is correctly done in fetchMasterTags() and fetchAllQuestions() functions. We can see the connect statement
at the last line which is simply telling Redux to connect
this QuestionPageWrapper component to the store so that
it can be notified of any important updates happening
in state of store that the component might be concerned
with.
{
import React, {useEffect} from react ;
import fetchMasterTags from ’./fetchMasterTags’
import fetchAllQuestions from
’./fetchAllQuestions’
import Filters from ’components/Filters/index.js’
import QuestionsContainer from
’components/QuestionsContainer/index.js’
const QuestionPageWrapper = ({masterTags,
questionsMasterData}) => {
Fig. 7. Filters
To fetch the list of master tags, there is an API whose
format is as shown below:
{
[
{
"id": 1,
"name": "price",
"display_name": "Price"
},
{
"id": 2,
"name": "location",
"display_name": "Location"
},
{
"id": 3,
"name": "legal_approvals",
"display_name": "Legal Approvals"
},
{...},
...
]
}
Now, let’s see how this API is consumed in UI components. There is component that
useEffect( () => {
fetchMasterTags();
fetchallQuestions();
}, [])
return(
)
}
const mapStateToProps = state =>{
return{
masterTags: state.masterTags,
questionsMasterData: state.data
}
}
export default connect
(mapStateToProps)(QuestionPageWrapper)
}
MapStateToProps function tells Redux to pass the current
state(global object) to this function so that the component
can extract all the required data it needs for rendering
and for rerendering in case any data updates occur.
Here ’masterTags’ and ’data’ from the store is extracted
in mapStateToProps function. Now the object that is
returned from the mapStateToProps function is passed
as argument to our component.
Then in it can be seen that
’masterTags’ data is passed to its child components
and . This is simply how
data flows through React-Redux web application. There
are still numerous other technologies like Server Side
Rendering, Webpack, Material-UI, @Emotion/Core that
Housing.com uses extensively, but considering limitation
on report length and taking into account reader’s attention
span, its better to end here.
VI. ACKNOWLEDGEMENT
Last but not the least, I’d like to thank everyone who
made possible the journey I covered delightful and played
a crucial role in my progress and where I stand right now.
I’d like to thank Nandan Chaudhary the most who mentored
me throughout the entirety of internship, who has paid heed to
my silliest of doubts and has never deprioritized my discussion
requests and reviews though I’m an intern. Secondly, I’d like to
thank Sukhdeep Handa equally who is my manager; his awareness of my current understanding/knowledge of ecosystem
and gradually kept giving tasks that always felt like another
challege to conquer and his collaborative nature. I’d like
to thank every member of Platform Growth Team, Housing
Frontend, Backend, QA team for their guidance throughout
internship. I’d like to thank all my fellow interns who have
been best stress busters and made life at office a bit chill. I’d
like to thank everyone who took training sessions, all the HR’s
who made interns feel equal part of the organization, organized
the internship and even gave opportunity to connect with the
CEO, CTO of the Elara Group. I’d like to thank every member
of Placement cell for their smooth and seamless execution of
placements by which I ultimately got an internship offer. I’d
like to thank Prof. Jaideep Mulherkar, BTP Coordinator for
giving opportunity to articulate internship work and experience. Lastly, I’d like to thank Meet Sinojia, my fellow friend
and classmate for proofreading my report.
VII. C ONCLUSION
I’d conclude that frontend ecosystem is so vast to grasp
and learn as a whole. Still its good to not be intimidated by
it but rather remain curious and learn the things that come
along the way. I always feel programming is never about a
particular language or a framework or a library, its about the
common patterns you observe, then learn and finally apply
in different environment that can solve problems and refine
our mental model and abstractions. I wish I venture into
unexplored territories in this vast ecosystem occasionally, face
novel problems once in a while and keep my spirit up by
solving some of those.
R EFERENCES
[1] React . Code-splitting. Accessed: May 14, 2020. [Online]. Available:
https://reactjs.org/docs/code-splitting.html
[2] MDN docs . Arrow function expressions. Accessed: May 14,
2020. [Online]. Available: https://developer.mozilla.org/en-US/docs/
Web/JavaScript/Reference/Functions/Arrow_functions
[3] Redux . Redux FAQ: Immutable Data. Accessed: May 14, 2020. [Online]. Available: https://redux.js.org/faq/immutable-data
[4] React . Using the Effect Hook. Accessed: May 14, 2020. [Online].
Available: https://reactjs.org/docs/hooks-effect.html