Create Linkedin clone app using MEAN stack

 Creating a LinkedIn clone using the MEAN stack (MongoDB, Express, Angular, Node.js) involves developing a frontend in Angular and a backend using Node.js and Express, with MongoDB as the database. This clone will include essential LinkedIn-like features like creating posts, viewing profiles, and interacting with the feed.

Overview of the MEAN Stack LinkedIn Clone

The MEAN stack consists of:

  • MongoDB: For storing data (e.g., users, posts).
  • Express: For handling HTTP requests.
  • Angular: For building the frontend.
  • Node.js: For running the backend.

Step-by-Step Guide

Step 1: Set up the Backend (Node.js + Express)

  1. Create a directory for the backend:
mkdir linkedin-backend cd linkedin-backend
  1. Initialize a Node.js project:
npm init -y
  1. Install necessary dependencies:
npm install express mongoose body-parser cors
  • express: To handle HTTP requests.
  • mongoose: For MongoDB object modeling.
  • body-parser: To parse incoming request bodies.
  • cors: For enabling cross-origin requests.
  1. Create the backend structure:
mkdir models routes controllers config touch server.js

Step 2: Set up MongoDB (MongoDB Atlas or Local)

  • You can set up a MongoDB instance on MongoDB Atlas (cloud) or locally on your computer.

Step 3: Backend Setup - Models and Routes

  1. Create User and Post Models:

In models/User.js:

// models/User.js const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, password: { type: String, required: true }, jobTitle: { type: String }, profilePic: { type: String }, createdAt: { type: Date, default: Date.now }, }); module.exports = mongoose.model('User', userSchema);

In models/Post.js:

// models/Post.js const mongoose = require('mongoose'); const postSchema = new mongoose.Schema({ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, content: { type: String, required: true }, createdAt: { type: Date, default: Date.now }, }); module.exports = mongoose.model('Post', postSchema);
  1. Create Routes for User and Post CRUD Operations:

In routes/userRoutes.js:

// routes/userRoutes.js const express = require('express'); const User = require('../models/User'); const router = express.Router(); // POST - Create new user (for simplicity, we are not hashing the password) router.post('/register', async (req, res) => { try { const { name, email, password, jobTitle, profilePic } = req.body; const newUser = new User({ name, email, password, jobTitle, profilePic }); await newUser.save(); res.status(201).json({ message: 'User created successfully!' }); } catch (err) { res.status(400).json({ message: err.message }); } }); module.exports = router;

In routes/postRoutes.js:

// routes/postRoutes.js const express = require('express'); const Post = require('../models/Post'); const router = express.Router(); // POST - Create a new post router.post('/', async (req, res) => { try { const { userId, content } = req.body; const newPost = new Post({ userId, content }); await newPost.save(); res.status(201).json({ message: 'Post created successfully!' }); } catch (err) { res.status(400).json({ message: err.message }); } }); // GET - Get all posts router.get('/', async (req, res) => { try { const posts = await Post.find().populate('userId', 'name profilePic'); res.status(200).json(posts); } catch (err) { res.status(400).json({ message: err.message }); } }); module.exports = router;
  1. Connect MongoDB and start Express server:

In server.js:

// server.js const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const bodyParser = require('body-parser'); const userRoutes = require('./routes/userRoutes'); const postRoutes = require('./routes/postRoutes'); const app = express(); // Middleware app.use(cors()); app.use(bodyParser.json()); // MongoDB connection mongoose.connect('mongodb://localhost:27017/linkedin-clone', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB connected')) .catch((err) => console.log('MongoDB connection error:', err)); // Routes app.use('/api/users', userRoutes); app.use('/api/posts', postRoutes); // Start the server app.listen(5000, () => { console.log('Server running on port 5000'); });

Now, run the server:

node server.js

Your Node.js backend should be running on http://localhost:5000.

Step 4: Set up the Frontend (Angular)

  1. Create a new Angular project:
ng new linkedin-clone-frontend cd linkedin-clone-frontend
  1. Install Angular HTTP Client:
ng generate module app-routing --flat --module=app npm install @angular/http
  1. Generate components for key pages:
ng generate component navbar ng generate component feed ng generate component post ng generate component profile
  1. Create Services for User and Post API calls:

In src/app/services/user.service.ts:

// user.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class UserService { private baseUrl = 'http://localhost:5000/api/users'; constructor(private http: HttpClient) {} registerUser(user: any): Observable<any> { return this.http.post(`${this.baseUrl}/register`, user); } }

In src/app/services/post.service.ts:

// post.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class PostService { private baseUrl = 'http://localhost:5000/api/posts'; constructor(private http: HttpClient) {} createPost(post: any): Observable<any> { return this.http.post(this.baseUrl, post); } getPosts(): Observable<any> { return this.http.get(this.baseUrl); } }

Step 5: Build the Feed Component (Displaying Posts)

In src/app/feed/feed.component.ts:

import { Component, OnInit } from '@angular/core'; import { PostService } from '../services/post.service'; @Component({ selector: 'app-feed', templateUrl: './feed.component.html', styleUrls: ['./feed.component.css'], }) export class FeedComponent implements OnInit { posts: any[] = []; newPost: string = ''; constructor(private postService: PostService) {} ngOnInit(): void { this.loadPosts(); } loadPosts() { this.postService.getPosts().subscribe((data: any) => { this.posts = data; }); } createPost() { if (this.newPost) { this.postService.createPost({ content: this.newPost, userId: 'user-id' }).subscribe(() => { this.loadPosts(); this.newPost = ''; }); } } }

In src/app/feed/feed.component.html:

<div class="feed-container"> <textarea [(ngModel)]="newPost" placeholder="What's on your mind?"></textarea> <button (click)="createPost()">Post</button> <div *ngFor="let post of posts" class="post"> <h3>{{ post.userId.name }}</h3> <p>{{ post.content }}</p> </div> </div>

Step 6: Navbar, Profile, and Post Components

  • Navbar: Display the application's navigation links (Home, Profile, etc.).
  • Profile: Display the user's profile data (name, profile picture, job title).
  • Post: Display and create new posts, integrating the PostService.

Step 7: Set up Angular Routing

In src/app/app-routing.module.ts:

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { FeedComponent } from './feed/feed.component'; import { ProfileComponent } from './profile/profile.component'; const routes: Routes = [ { path: '', component: FeedComponent }, { path: 'profile', component: ProfileComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule {}

Step 8: Run the Application

  1. Start the Angular frontend:
ng serve
  1. Now, visit http://localhost:4200 and interact with the feed, create posts, and view user profiles.

Conclusion

You've successfully set up a basic LinkedIn clone using the MEAN stack. Here's a quick summary of the key components:

  • Backend (Node.js + Express): Manages user and post data using MongoDB.
  • Frontend (Angular): Displays posts, allows post creation, and user interaction.
  • MongoDB: Stores user profiles and posts.

This clone can be expanded with additional features like user authentication (JWT), commenting on posts, liking posts, and more. You can also enhance the UI by integrating additional UI frameworks or custom styling with Tailwind CSS.

Comments

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

oAuth in angular