Updated Angular Project

FIX ErrorObj from TRESTClient
This commit is contained in:
Daniele Teti 2017-05-12 00:25:46 +02:00
parent a0198aa2e8
commit d2b024ff43
73 changed files with 96 additions and 57 deletions

View File

@ -1,6 +1,6 @@
program Angular2SampleServer;
{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
uses
System.SysUtils,
@ -8,44 +8,34 @@ uses
Winapi.ShellAPI,
Web.WebReq,
Web.WebBroker,
MVCFramework.Commons,
IdHTTPWebBrokerBridge,
CustomersControllerU in 'CustomersControllerU.pas',
WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule},
WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule} ,
CustomersTDGU in 'CustomersTDGU.pas' {CustomersTDG: TDataModule};
{$R *.res}
procedure RunServer(APort: Integer);
var
LInputRecord: TInputRecord;
LEvent: DWord;
LHandle: THandle;
LServer: TIdHTTPWebBrokerBridge;
begin
Writeln('** DMVCFramework Server **');
Writeln('** DMVCFramework Server ** ' + DMVCFRAMEWORK_VERSION);
Writeln(Format('Starting HTTP Server on port %d', [APort]));
LServer := TIdHTTPWebBrokerBridge.Create(nil);
try
LServer.DefaultPort := APort;
LServer.Active := True;
{ more info about MaxConnections
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdCustomTCPServer_MaxConnections.html}
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdCustomTCPServer_MaxConnections.html }
LServer.MaxConnections := 0;
{ more info about ListenQueue
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdCustomTCPServer_ListenQueue.html}
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdCustomTCPServer_ListenQueue.html }
LServer.ListenQueue := 200;
{ Comment the next line to avoid the default browser startup }
ShellExecute(0, 'open', PChar('http://localhost:' + inttostr(APort)), nil, nil, SW_SHOWMAXIMIZED);
Writeln('Press ESC to stop the server');
LHandle := GetStdHandle(STD_INPUT_HANDLE);
while True do
begin
Win32Check(ReadConsoleInput(LHandle, LInputRecord, 1, LEvent));
if (LInputRecord.EventType = KEY_EVENT) and
LInputRecord.Event.KeyEvent.bKeyDown and
(LInputRecord.Event.KeyEvent.wVirtualKeyCode = VK_ESCAPE) then
break;
end;
Writeln('Press RETURN to stop the server');
ReadLn;
finally
LServer.Free;
end;
@ -63,4 +53,5 @@ begin
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@ -76,7 +76,8 @@ begin
lParams.Add('User_Name=sysdba');
lParams.Add('Password=masterkey');
lParams.Add('Pooled=true');
FDManager.AddConnectionDef(PRIVATE_CONN_DEF_NAME, 'FB', lParams);
FDManager.AddConnectionDef(PRIV
ATE_CONN_DEF_NAME, 'FB', lParams);
finally
lParams.Free;
end;

View File

@ -27,8 +27,9 @@
"zone.js": "^0.6.23"
},
"devDependencies": {
"@angular/cli": "^1.0.3",
"@angular/compiler-cli": "^4.1.2",
"@types/jasmine": "^2.2.30",
"angular-cli": "1.0.0-beta.16",
"codelyzer": "~0.0.26",
"jasmine-core": "2.4.1",
"jasmine-spec-reporter": "2.5.0",

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -41,7 +41,7 @@ type
implementation
uses
System.SysUtils;
System.SysUtils, System.RegularExpressions;
{ TBaseBO }
@ -70,22 +70,23 @@ end;
procedure TArticle.CheckDelete;
begin
inherited;
// if Price > 0 then
// raise Exception.Create('Cannot delete an article with a price greater than 0 (yes, it is a silly check)');
if Price <= 5 then
raise Exception.Create('Cannot delete an article with a price below 5 euros (yes, it is a silly check)');
end;
procedure TArticle.CheckInsert;
begin
inherited;
if length(Code) < 3 then
raise Exception.Create('Article code cannot be less than 3 chars');
if not TRegEx.IsMatch(Code, '^C[0-9]{2,4}') then
raise Exception.Create('Article code must be in the format "CXX or CXXX or CXXXX"');
end;
procedure TArticle.CheckUpdate;
begin
inherited;
if length(Code) < 3 then
raise Exception.Create('Article code cannot be less than 3 chars');
CheckInsert;
if Price <= 2 then
raise Exception.Create('We cannot sell so low cost pizzas!');
end;
procedure TArticle.SetCode(const Value: string);

View File

@ -61,8 +61,7 @@ var
begin
GetArticlesService.StartTransaction;
try
Article := GetArticlesService.GetByID
(Context.Request.ParamsAsInteger['id']);
Article := GetArticlesService.GetByID(id);
try
GetArticlesService.Delete(Article);
finally
@ -86,7 +85,7 @@ var
begin
Article := Context.Request.BodyAs<TArticle>;
try
Article.id := Context.Request.ParamsAsInteger['id'];
Article.id := id;
GetArticlesService.Update(Article);
Render(200, 'Article Updated');
finally
@ -99,8 +98,7 @@ var
Article: TArticle;
begin
try
Article := GetArticlesService.GetByID
(Context.Request.ParamsAsInteger['id']);
Article := GetArticlesService.GetByID(id);
Render(Article);
except
on E: EServiceException do

View File

@ -9,12 +9,14 @@ object dmMain: TdmMain
'Password=masterkey'
'DriverID=FB')
ConnectedStoredUsage = []
Connected = True
LoginPrompt = False
BeforeConnect = ConnectionBeforeConnect
Left = 64
Top = 48
end
object dsArticles: TFDQuery
Active = True
Connection = Connection
UpdateOptions.AssignedValues = [uvFetchGeneratorsPoint, uvGeneratorName]
UpdateOptions.FetchGeneratorsPoint = gpImmediate
@ -33,13 +35,15 @@ object dmMain: TdmMain
'INSERT INTO ARTICOLI'
'(ID, CODICE, DESCRIZIONE, PREZZO)'
'VALUES (:NEW_ID, :NEW_CODICE, :NEW_DESCRIZIONE, :NEW_PREZZO)'
'RETURNING ID, CODICE, DESCRIZIONE, PREZZO')
'RETURNING ID {INTO :ID}')
ModifySQL.Strings = (
'UPDATE ARTICOLI'
'SET CODICE = :NEW_CODICE, DESCRIZIONE = :NEW_DESCRIZIONE, '
'SET ID = :NEW_ID, CODICE = :NEW_CODICE, DESCRIZIONE = :NEW_DESCR' +
'IZIONE, '
' PREZZO = :NEW_PREZZO'
'WHERE ID = :OLD_ID'
'RETURNING ID, CODICE, DESCRIZIONE, PREZZO')
'RETURNING ID')
DeleteSQL.Strings = (
'DELETE FROM ARTICOLI'
'WHERE ID = :OLD_ID')

View File

@ -28,9 +28,10 @@ implementation
procedure TdmMain.ConnectionBeforeConnect(Sender: TObject);
begin
// currently, this demo uses firebird 3.0
// currently, this demo uses firebird 2.5
// if you want to use firebird 2.5, you can use the file ORDERSMANAGER_FB25.FDB
Connection.Params.Values['Database'] := '..\..\data\ORDERSMANAGER_FB30.FDB';
// Connection.Params.Values['Database'] := '..\..\data\ORDERSMANAGER_FB30.FDB';
Connection.Params.Values['Database'] := '..\..\data\ORDERSMANAGER_FB25.FDB';
end;
end.

View File

@ -42,7 +42,8 @@ begin
AArticolo.CheckInsert;
Cmd := FDM.updArticles.Commands[arInsert];
TFireDACUtils.ObjectToParameters(Cmd.Params, AArticolo, 'NEW_');
Cmd.OpenOrExecute;
Cmd.Execute;
AArticolo.ID := Cmd.ParamByName('ID').AsInteger;
end;
procedure TArticlesService.Delete(AArticolo: TArticle);

View File

@ -151,6 +151,12 @@ end;
procedure TMainForm.ShowError(const AResponse: IRESTResponse);
begin
if AResponse.HasError then
MessageDlg(
AResponse.Error.HTTPError.ToString + ': ' + AResponse.Error.ExceptionMessage + sLineBreak +
'[' + AResponse.Error.ExceptionClassname + ']',
mtError, [mbOK], 0)
else
MessageDlg(
AResponse.ResponseCode.ToString + ': ' + AResponse.ResponseText + sLineBreak +
AResponse.BodyAsString,

View File

@ -19,11 +19,12 @@
"mobile": false,
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../node_modules/animate.css/animate.min.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}

View File

@ -21,6 +21,7 @@
"@angular/platform-browser": "^2.3.1",
"@angular/platform-browser-dynamic": "^2.3.1",
"@angular/router": "^3.3.1",
"animate.css": "^3.5.2",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"ng2-bootstrap": "^1.2.1",
@ -29,10 +30,10 @@
"zone.js": "^0.7.6"
},
"devDependencies": {
"@angular/cli": "^1.0.3",
"@angular/compiler-cli": "^2.3.1",
"@types/jasmine": "2.5.38",
"@types/node": "^6.0.42",
"angular-cli": "1.0.0-beta.24",
"codelyzer": "~2.0.0-beta.1",
"jasmine-core": "2.5.2",
"jasmine-spec-reporter": "2.5.0",

View File

@ -14,7 +14,7 @@
<input [(ngModel)]="article.price" class="form-control" id="prezzo" name="prezzo" />
</div>
<div>
<button type="button" class="btn btn-success" (click)="doSaveArticle()">Save Article</button>
<button type="submit" class="btn btn-success" (click)="doSaveArticle()">Save Article</button>
<button type="button" class="btn btn-normal" (click)="doCancel()">Cancel</button>
</div>
</form>

View File

@ -1,5 +1,5 @@
<div class="jumbotron">
<h1>DMVCFramework</h1>
<p>This demo uses DMVCFramework, typescript and Angular2</p>
<p>This demo uses DMVCFramework, typescript and Angular</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>

View File

@ -2,10 +2,11 @@ import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Article } from '../models/articolo';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
@Injectable()
export class ArticlesService {
private _articoliUrl = 'http://localhost:8080/articles'; // URL to web api
private _articoliUrl = environment.URL; // 'http://localhost:8080/articles'; // URL to web api
constructor(private http: Http) { }
@ -25,7 +26,14 @@ export class ArticlesService {
private handleError(error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error.text);
let err = null;
try {
err = error.json();
} catch (ex) {
err = { 'reasonstring': 'empty reasonstring', 'message': 'empty message' };
}
console.error(err);
alert(err.message);
return Observable.throw(error.text || 'Server error');
// return Observable.throw('Server error');
}
@ -54,6 +62,6 @@ export class ArticlesService {
}
public removeArticolo(articolo: Article) {
return this.http.delete(this._articoliUrl + '/' + articolo.id);
return this.http.delete(this._articoliUrl + '/' + articolo.id).catch(this.handleError);
}
}

View File

@ -4,5 +4,6 @@
// The list of which env maps to which file can be found in `angular-cli.json`.
export const environment = {
production: false
production: false,
URL: 'http://localhost:8080/articles' // URL to web api
};

View File

@ -7,8 +7,32 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<style>
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
border-bottom: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 1s linear infinite;
animation: spin 1.5s linear infinite;
margin: auto;
margin-top: 10%;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<app-root>Loading...</app-root>
<app-root><div class="loader"></div></app-root>
</body>
</html>