9032. Online Judge - Others
MEAN, Angular, Express, and MongoDB


Build online judge application with MEAN stack(MongoDB, Express, Angular and Node.js).

1. Reactive Form

1.1 Form Validation

1.2 Server side Validation

1.3 Controls

Using ControlValueAccessor to Create Custom Form Controls in Angular, rating star https://alligator.io/angular/custom-form-control/

1.4 Angular basis

1.5 Two Way Data-Binding

Create 2 way data-binding with @Output.

//result-panel.component.ts
@Input() testResult: number;
@Output() testResultChange = new EventEmitter<number>();

Notify parent if value changes.

//result-panel.component.ts
close() {
  this.testResult = 0;
  this.testResultChange.emit(0); // notify parent
}

Use [(testResult)]=”testResult”, not [testResult]=”testResult” to accept value change from child component.

<!-- algorithm-question.component.html -->
<app-widget-result-panel [(testResult)]="testResult" [resultMessage]="resultMessage"></app-widget-result-panel>

2. MongoDB

2.1 Aggregation

db.submissions.aggregate([
    { $sort: { "timecreated": -1 } },
    { $group: { _id: "$language", latest: { $first: "$$ROOT" } }},
    { $project : {_id : "$latest._id", username : "$latest.username", questionname : "$latest.questionname", solution : "$latest.solution", language : "$latest.language", status : "$latest.status", timeupdated : "$latest.timeupdated", timesubmitted : "$latest.timesubmitted", runtime : "$latest.runtime" }},
    { $sort: { "language": 1 } }
]).pretty()

3. RESTful API

4. Issues

4.1 Error: No default engine was specified and no extension was provided

The res.render stuff will throw an error if you’re not using a view engine.

If you just want to serve json replace the res.render(‘error’, { error: err }); lines in your code with:

res.json({ error: err })
PS: People usually also have message in the returned object:

res.status(err.status || 500);
res.json({
  message: err.message,
  error: err
});

4.2 ErrorHttpInterceptor

when using HttpInterceptor to handle http request error, do not call

//ErrorHttpInterceptor.intercept()
return next.handle(request);

It will make zone.js to send second same request to server. Instead, throw the error.

//ErrorHttpInterceptor.intercept()
return _throw(this.messages);

5. Todo

  • Collaborative editor
  • IM message.
  • unit test with mocha
  • docker
  • collaborative online judge system: google doc + online compiler.
  • create pipe for time date, create pipe for shorten the description in table.
  • knowledge: type script, angular 4, rxjs,
  • how to get dev and prod, to show error message in http.interceptor.ts

6. Reference