mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
Updated Angular Project
FIX ErrorObj from TRESTClient
This commit is contained in:
parent
a0198aa2e8
commit
d2b024ff43
Binary file not shown.
@ -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.
|
Binary file not shown.
@ -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;
|
@ -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",
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -151,10 +151,16 @@ end;
|
||||
|
||||
procedure TMainForm.ShowError(const AResponse: IRESTResponse);
|
||||
begin
|
||||
MessageDlg(
|
||||
AResponse.ResponseCode.ToString + ': ' + AResponse.ResponseText + sLineBreak +
|
||||
AResponse.BodyAsString,
|
||||
mtError, [mbOK], 0);
|
||||
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,
|
||||
mtError, [mbOK], 0);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -19,14 +19,15 @@
|
||||
"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": [],
|
||||
"environments": {
|
||||
"source": "environments/environment.ts",
|
||||
"dev": "environments/environment.ts",
|
||||
"prod": "environments/environment.prod.ts"
|
||||
}
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"prod": "environments/environment.prod.ts"
|
||||
}
|
||||
}
|
||||
],
|
||||
"addons": [],
|
@ -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",
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user