title: How to convert observable<User> to Obserable<boolean> in angular 4
body: <p>i want to implement canActivate() method so to restrict admin routes. I'm returning observable of type user in checkAdmin method (in my service file) but canActivate method's return type is observable of type boolean.
  So i'm unable to convert observable of type "User" to observable of boolean. Please help me as i'm new in angular and mean stack</p>
  
  <p>user schema model </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>/* ===================
     Import Node Modules
  =================== */
  const mongoose = require('mongoose'); // Node Tool for MongoDB
  mongoose.Promise = global.Promise; // Configure Mongoose Promises
  const Schema = mongoose.Schema; // Import Schema from Mongoose
  const bcrypt = require('bcrypt-nodejs'); // A native JS bcrypt library for NodeJS
  
  // Validate Function to check e-mail length
  let emailLengthChecker = (email) =&gt; {
    // Check if e-mail exists
    if (!email) {
      return false; // Return error
    } else {
      // Check the length of e-mail string
      if (email.length &lt; 5 || email.length &gt; 30) {
        return false; // Return error if not within proper length
      } else {
        return true; // Return as valid e-mail
      }
    }
  };
  
  // Validate Function to check if valid e-mail format
  let validEmailChecker = (email) =&gt; {
    // Check if e-mail exists
    if (!email) {
      return false; // Return error
    } else {
      // Regular expression to test for a valid e-mail
      const regExp = new RegExp(/^(([^&lt;&gt;()\[\]\\.,;:\s@"]+(\.[^&lt;&gt;()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
      return regExp.test(email); // Return regular expression test results (true or false)
    }
  };
  
  // Array of Email Validators
  const emailValidators = [
    // First Email Validator
    {
      validator: emailLengthChecker,
      message: 'E-mail must be at least 5 characters but no more than 30'
    },
    // Second Email Validator
    {
      validator: validEmailChecker,
      message: 'Must be a valid e-mail'
    }
  ];
  
  // Validate Function to check username length
  let usernameLengthChecker = (username) =&gt; {
    // Check if username exists
    if (!username) {
      return false; // Return error
    } else {
      // Check length of username string
      if (username.length &lt; 3 || username.length &gt; 15) {
        return false; // Return error if does not meet length requirement
      } else {
        return true; // Return as valid username
      }
    }
  };
  
  // Validate Function to check if valid username format
  let validUsername = (username) =&gt; {
    // Check if username exists
    if (!username) {
      return false; // Return error
    } else {
      // Regular expression to test if username format is valid
      const regExp = new RegExp(/^[a-zA-Z0-9]+$/);
      return regExp.test(username); // Return regular expression test result (true or false)
    }
  };
  
  // Array of Username validators
  const usernameValidators = [
    // First Username validator
    {
      validator: usernameLengthChecker,
      message: 'Username must be at least 3 characters but no more than 15'
    },
    // Second username validator
    {
      validator: validUsername,
      message: 'Username must not have any special characters'
    }
  ];
  
  // Validate Function to check password length
  let passwordLengthChecker = (password) =&gt; {
    // Check if password exists
    if (!password) {
      return false; // Return error
    } else {
      // Check password length
      if (password.length &lt; 8 || password.length &gt; 35) {
        return false; // Return error if passord length requirement is not met
      } else {
        return true; // Return password as valid
      }
    }
  };
  
  // Validate Function to check if valid password format
  let validPassword = (password) =&gt; {
    // Check if password exists
    if (!password) {
      return false; // Return error
    } else {
      // Regular Expression to test if password is valid format
      const regExp = new RegExp(/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d])(?=.*?[\W]).{8,35}$/);
      return regExp.test(password); // Return regular expression test result (true or false)
    }
  };
  
  // Array of Password validators
  const passwordValidators = [
    // First password validator
    {
      validator: passwordLengthChecker,
      message: 'Password must be at least 8 characters but no more than 35'
    },
    // Second password validator
    {
      validator: validPassword,
      message: 'Must have at least one uppercase, lowercase, special character, and number'
    }
  ];
  
  // User Model Definition
  const userSchema = new Schema({
    email: { type: String, required: true, unique: true, lowercase: true, validate: emailValidators },
    username: { type: String, required: true, unique: true, lowercase: true, validate: usernameValidators },
    password: { type: String, required: true, validate: passwordValidators },
    isAdmin: { type: Boolean, default: false }
  });
  
  // Schema Middleware to Encrypt Password
  userSchema.pre('save', function(next) {
    // Ensure password is new or modified before applying encryption
    if (!this.isModified('password'))
      return next();
  
    // Apply encryption
    bcrypt.hash(this.password, null, null, (err, hash) =&gt; {
      if (err) return next(err); // Ensure no errors
      this.password = hash; // Apply encryption to password
      next(); // Exit middleware
    });
  });
  
  // Methods to compare password to encrypted password upon login
  userSchema.methods.comparePassword = function(password) {
    return bcrypt.compareSync(password, this.password); // Return comparison of login password to password in database (true or false)
  };
  
  // Export Module/Schema
  module.exports = mongoose.model('User', userSchema);</code></pre>
  </div>
  </div>
  </p>
  
  <p>http routes which contains /profile route to get the user from mongodb database</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const User = require('../models/user'); // Import User Model Schema
  
  const jwt = require('jsonwebtoken');
  const config = require('../config/database');
  
  module.exports = (router) =&gt; {
    /* ==============
       Register Route
    ============== */
    router.post('/register', (req, res) =&gt; {
      // Check if email was provided
      if (!req.body.email) {
        res.json({ success: false, message: 'You must provide an e-mail' }); // Return error
      } else {
        // Check if username was provided
        if (!req.body.username) {
          res.json({ success: false, message: 'You must provide a username' }); // Return error
        } else {
          // Check if password was provided
          if (!req.body.password) {
            res.json({ success: false, message: 'You must provide a password' }); // Return error
          } else {
            // Create new user object and apply user input
            let user = new User({
              email: req.body.email.toLowerCase(),
              username: req.body.username.toLowerCase(),
              password: req.body.password
            });
            // Save user to database
            user.save((err) =&gt; {
              // Check if error occured
              if (err) {
                // Check if error is an error indicating duplicate account
                if (err.code === 11000) {
                  res.json({ success: false, message: 'Username or e-mail already exists' }); // Return error
                } else {
                  // Check if error is a validation rror
                  if (err.errors) {
                    // Check if validation error is in the email field
                    if (err.errors.email) {
                      res.json({ success: false, message: err.errors.email.message }); // Return error
                    } else {
                      // Check if validation error is in the username field
                      if (err.errors.username) {
                        res.json({ success: false, message: err.errors.username.message }); // Return error
                      } else {
                        // Check if validation error is in the password field
                        if (err.errors.password) {
                          res.json({ success: false, message: err.errors.password.message }); // Return error
                        } else {
                          res.json({ success: false, message: err }); // Return any other error not already covered
                        }
                      }
                    }
                  } else {
                    res.json({ success: false, message: 'Could not save user. Error: ', err }); // Return error if not related to validation
                  }
                }
              } else {
                res.json({ success: true, message: 'Acount registered!' }); // Return success
              }
            });
          }
        }
      }
    });
  
    router.get('/checkEmail/:email', (req, res) =&gt; {
      if (!req.params.email) {
        res.json({ success: false, message: 'email not provided'});
      } else {
        User.findOne({ email: req.params.email}, (err, user) =&gt; {
          if (err) {
            res.json({ success: false, message: err});
          } else {
            if (user) {
              res.json({ success: false, message: 'email taken'});
            } else {
              res.json({ success: true, message: 'email available'});
            }
          }
        });
      }
    });
  
    router.get('/checkUsername/:username', (req, res) =&gt; {
      if (!req.params.username) {
        res.json({ success: false, message: 'username not provided'});
      } else {
        User.findOne({ username: req.params.username}, (err, user) =&gt; {
          if (err) {
            res.json({ success: false, message: err});
          } else {
            if (user) {
              res.json({ success: false, message: 'username taken'});
            } else {
              res.json({ success: true, message: 'username available'});
            }
          }
        });
      }
    });
  
    router.post('/login', (req, res) =&gt; {
      if (!req.body.username) {
        res.json({ success: false, message: 'No username was provided'});
      } else {
        if (!req.body.password) {
          res.json({ success: false, message: 'No password was provided'});
        } else {
          User.findOne({ username: req.body.username.toLowerCase() }, (err, user) =&gt; {
            if (err) {
              res.json({ success: false, message: err});
            } else {
              if (!user) {
                res.json({ success: false, message: 'No user exist'});
              } else {
                const validPassword = user.comparePassword(req.body.password);
                if (!validPassword) {
                  res.json({ success: false, message: 'password invalid'});
                } else {
                  const token = jwt.sign({userId: user._id}, config.secret, {expiresIn: '24h'});
                  res.json({ success: true, message: 'Success!', token: token, user: {username: user.username}});
                }
              }
            }
          });
        }
      }
    });
  
  // MIDDLEWARE TO INTERCEPT HEADERS
  // THIS MIDDLEWARE DECRYPTS THE TOKEN
    router.use((req, res, next) =&gt; {
      const token = req.headers['authorization']; // whenever a request coming from angular2 with headers attached it is going to search fot this header
      if (!token) {
        res.json({ success: false, message: 'No token provided'});
      } else {
        jwt.verify(token, config.secret, (err, decoded) =&gt; {
          if (err) {
            res.json({ success: false, message: 'invalid token' + err});
          } else {
            req.decoded = decoded;
            next();
          }
        });
      }
    })
  // ANY ROUTES COMING AFTER THIS MIDDLEWARE WILL PASS THROUGH THE SAME
  
  // BELOW METHOD TAKES THE DECRYPTED TOKEN FIND THE USER
    router.get('/profile', (req, res) =&gt; {
      User.findOne({ _id: req.decoded.userId }).select('username email').exec((err, user) =&gt; {
        if (err) {
          res.json({ success: false, message: err});
        } else {
          if (!user) {
            res.json({ success: false, message: 'user not found'});
          } else {
            res.json({ success: true, user: user });
          }
        }
      });
    });
  
    return router; // Return router object to main index.js
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>this the service file  which call the http method to get the user </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Injectable } from '@angular/core';
  import 'rxjs/add/operator/map';
  import { Http, Headers, RequestOptions } from '@angular/http';
  // import { map } from "rxjs/operators";
  // import { map } from 'rxjs/operators';
  
  import { switchMap } from 'rxjs/operators';
  import { tokenNotExpired } from 'angular2-jwt';
  import { User } from '../shared/user';
  import { Observable } from 'rxjs/Observable';
  import 'rxjs/add/observable/of';
  @Injectable()
  export class AuthService {
  
    domain = 'http://localhost:3000';
    authToken;
    user;
    options;
  
    constructor(private http: Http) { }
  
    registerUser(user) {
      return this.http.post(this.domain + '/authentication/register', user).map(res =&gt; res.json());
    }
  
    createAuthenticationHeaders() {
      this.loadToken();
      this.options = new RequestOptions({
        headers : new Headers({
          'Content-Type': 'application/json',
          'authorization': this.authToken
        })
      });
  
    }
  
    loadToken() {
      this.authToken = localStorage.getItem('token');
    }
    checkUsername(username) {
      return this.http.get(this.domain + '/authentication/checkUsername/' + username).map(res =&gt; res.json());
    }
  
    checkEmail(email) {
      return this.http.get(this.domain + '/authentication/checkEmail/' + email).map(res =&gt; res.json());
    }
  
    login(user) {
      return this.http.post(this.domain + '/authentication/login', user).map(res =&gt; res.json());
    }
  
  
  
    logout() {
      this.authToken = null;
      this.user = null;
      localStorage.clear();
    }
    storeUserData(token, user) {
      localStorage.setItem('token', token);
      localStorage.setItem('user', JSON.stringify(user));
      this.authToken = token;
      this.user = user;
    }
  
    getProfile() {
      this.createAuthenticationHeaders();
      return this.http.get(this.domain + '/authentication/profile', this.options).map(res =&gt; res.json());
    }
  
    checkAdmin(): Observable&lt;User&gt; {
      this.createAuthenticationHeaders();
      return this.http.get(this.domain + '/authentication/profile', this.options).map(res =&gt; res.json());
    }
  
    loggedIn() {
      return tokenNotExpired();
    }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>this is the admin auth guard file in which i'm having problem in canActivate() method to convert observable of type user to observable of boolean</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Injectable } from '@angular/core';
  import { CanActivate, Router, ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
  import { AuthService } from '../services/auth.service';
  import 'rxjs/add/operator/switchMap';
  import 'rxjs/add/operator/map';
  import { Observable } from 'rxjs/Observable';
  import { User } from '../shared/user';
  import { Subject } from 'rxjs/Subject';
  
  @Injectable()
  export class AdminAuthGuard implements CanActivate {
  
      redirectUrl;
      constructor(private authService: AuthService, private router: Router) {
  
      }
  
      canActivate(router: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
          /*return this.authService.user.switchMap(user =&gt; this.authService.getProfile1())
          .map(user =&gt; user.isAdmin);*/
          const subject = new Subject();
      // get user access levels
          return this.authService.checkAdmin()
              .map(user =&gt; {
              const isAdmin = user.isAdmin;
              if (isAdmin === true ) {
                  return true;
              }
              return false;
              });
      }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>Application user interface</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>export interface User {
      username: string;
      email: string;
      isAdmin: boolean;
  }</code></pre>
  </div>
  </div>
  </p>