Search code examples
angularmongodbangular8mongoose-schemamongoose-populate

Can I pull a value from another document, if the schemas reference each other?


I have a job posts collection and an applicant collection. The applicants schema references the job posts in MongoDB, but when I pull it into my Angular 8 frontend HTML, i want to display the postTitle in the applicant.component.html.

I was told to use the mongoose findOne() but they did not mention where to put that code, and putting it anywhere in the applicant.component.ts just gave me error messages.

How can that be written into the applicant.component.ts or adding to my routes file that makes it work?

both schemas

Post

var PostSchema = new mongoose.Schema({
  category : { type: Schema.Types.ObjectId, ref: 'Category' },
  id: String,
  postTitle: String,
  postAuthor: String,
  postDescription: String,
  postQualifications: String,
  postReference: String,
  updated: { type: Date, default: Date.now },
});

Applicant

var ApplicantSchema = new mongoose.Schema ({
    post : { type: Schema.Types.ObjectId, ref: 'Post' },
    id: String,
    appName: String,
    appPhone: String,
    appEmail: String,
    appAddress1: String,
    appAddress2: String,
    appResume: String,
    updated: { type: Date, default: Date.now }
});

HTML

<div class="button-row">
        <a mat-flat-button color="primary" [routerLink]="['/applicant']">Back</a>
      </div>
      <hr>
    <div class="row application">
        <div class="col-md-6">
            <h3>{{applicant.appName}}</h3> 
            <h4>Applying for: {{applicant.post}} || Need post.postTitle </h4>
            <h4>Submitted: {{applicant.updated | date: 'dd MMM yyyy'}}</h4>
        </div>
        <div class="col-md-5">
            <h4>{{applicant.appPhone}}</h4>
            <h4>{{applicant.appEmail}}</h4>
            <h4>{{applicant.appAddress1}}, </h4>
            <h4>{{applicant.appAddress2}}</h4>
        </div>
        <div class="col-md-1">
            <a class="btn btn-block" button (click)="deleteApplicant(applicant.id)">
                <mat-icon>delete</mat-icon>
            </a>
        </div>
        <br>
        <div class="col-md-12">
            <p innerHTML={{applicant.appResume}}></p>
        </div>
    </div>

TS

export class ApplicantDetailsComponent implements OnInit {

    applicant: Applicant = { 
      id: null, 
      appPhone: '',
      appEmail: '',
      appName: '', 
      appAddress1: '',
      appAddress2: '',
      post: '', 
      appResume: '',
      updated: null 
    };

  isLoadingResults = true;
  post: Post[] = [];

  constructor(private route: ActivatedRoute, private api: ApplicantService, private router: Router, private postApi: PostService) { }

  ngOnInit() {
    this.getPost()
    this.getApplicantDetails(this.route.snapshot.params.id);
  }

  getApplicantDetails(id: any) {
    this.api.getApplicant(id)
      .subscribe((data: any) => {
        this.applicant = data;
        this.applicant.id = data._id;
        console.log(this.applicant);
        this.isLoadingResults = false;
      });
  }

  deleteApplicant(id: any) {
    this.isLoadingResults = true;
    this.api.deleteApplicant(id)
      .subscribe(res => {
        this.isLoadingResults = false;
        this.router.navigate(['/applicant']);
      }, (err) => {
        console.log(err);
        this.isLoadingResults = false;
      }
      );
  }

  getPost() {
    this.postApi.getPost(this.post)
      .subscribe((res: any) => {
        this.post = res._id;
        console.log(this.post);
        this.isLoadingResults = false;
      }, err => {
        console.log(err);
        this.isLoadingResults = false;
      });
  }


}

Applicant routes

router.get('/', passport.authenticate('jwt', { session: false}), function(req, res) {
  var token = getToken(req.headers);
  if (token) {
    Applicant.find(function (err, applicants) {
      if (err) return next(err);
      res.json(applicants);
    });
  } else {
    return res.status(403).send({success: false, msg: 'Unauthorized.'});
  }
});

router.get('/:id', passport.authenticate('jwt', { session: false}), function(req, res, next) {
var token = getToken(req.headers);
if (token) {
  Applicant.findById(req.params.id, function (err, applicant) {
    if (err) return next(err);
    res.json(applicant);
  });
} else {
  return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
});

router.post('/', passport.authenticate('jwt', { session: false}), function(req, res, next) {
var token = getToken(req.headers);
if (token) {
  Applicant.create(req.body, function (err, applicant) {
    if (err) return next(err);
    res.json(applicant);
  });
} else {
  return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
});

router.put('/:id', passport.authenticate('jwt', { session: false}), function(req, res, next) {
var token = getToken(req.headers);
if (token) {
  Applicant.findByIdAndUpdate(req.params.id, req.body, function (err, applicant) {
    if (err) return next(err);
    res.json(applicant);
  });
} else {
  return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
});

router.delete('/:id', passport.authenticate('jwt', { session: false}), function(req, res, next) {
var token = getToken(req.headers);
if (token) {
  Applicant.findByIdAndRemove(req.params.id, req.body, function (err, applicant) {
    if (err) return next(err);
    res.json(applicant);
  });
} else {
  return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
});

getToken = function (headers) {
if (headers && headers.authorization) {
  var parted = headers.authorization.split(' ');
  if (parted.length === 2) {
    return parted[1];
  } else {
    return null;
  }
} else {
  return null;
}
};

module.exports = router;

Tried this as well

HTML

<div class="col-md-6">
        <h3>{{applicant.appName}}</h3> 
        <h4 *ngIf="{{post._id}} === {{applicant.post}}, show">Applying for: {{post.postTitle}} </h4>
        <h4>Submitted: {{applicant.updated | date: 'dd MMM yyyy'}}</h4>
    </div>

Solution

  • The answer was to fetch posts from my applicant.js routing folder

    router.get('/:id', passport.authenticate('jwt', { session: false }), function (req, res, next) {
      var token = getToken(req.headers);
      if (token) {
        Applicant.findById(req.params.id, function (err, applicant) {
          if (err) return next(err);
          console.log(applicant.post);
          Post.findOne({_id: applicant.post}).exec(function (err, post) {
            if (err) return next(err);
            console.log(post);
            res.json([applicant, post]);
          });
    
        });
      } else {
        return res.status(403).send({ success: false, msg: 'Unauthorized.' });
      }
    });