Store.sync() lose extraParams - extjs5

I have treeStore with extraParams
proxy: {
extraParams: {hierarchy_id: '5'},
api: {
update: jsonrpc.dim_hier.modifyData,
read: jsonrpc.dim_hier.getData,
create: jsonrpc.dim_hier.addData,
destroy: jsonrpc.dim_hier.deleteData
}
}
but store.sync() does not send to server this extraParams.
I tried to send param like this
component.getStore().getProxy().setExtraParam(
'hierarchy_id', hierarchy_id);
component.getStore().sync();
and this
component.getStore().sync({
params :{
hierarchy_id: hierarchy_id}
});
and
component.getStore().getProxy().setExtraParams({
hierarchy_id: hierarchy_id
});
component.getStore().sync();
but none of this works
What did I do wrong?
Thank for any help

In method doRequest (Ext.data.proxy.Direct)
if (action === 'read') {
params = request.getParams();
} else {
params = request.getJsonData();
}
I override this method like this
params = request.getParams();
if (action !== 'read') {
params.rows = request.getJsonData();
}}

Try it:
var store = component.getStore();
Ext.apply(store.proxy, {
extraParams: {
hierarchy_id: hierarchy_id
}
});

TO SEND THE extraParams ALWAYS NOT ONLY ON READ OPERATIONS (CREATE, DESTROY, UPDATE)
I extended
Ext.data.proxy.Direct
and override
doRequest
It worked like a charm.
Using ExtJs 4.1.1
The original code is:
if (operation.action == 'read') {
// We need to pass params
method = fn.directCfg.method;
args = method.getArgs(params, me.paramOrder, me.paramsAsHash);
} else {
args.push(request.jsonData);
}
I changed it to:
method = fn.directCfg.method;
args = method.getArgs(params, me.paramOrder, me.paramsAsHash);
if(operation.action !== 'read'){
args.push(request.jsonData);
}
Took the idea from here https://www.sencha.com/forum/showthread.php?282879-ExtraParams-Store-Create
Notice: your store will have a proxy of whatever you put on the alias of the class you created. Your alias will be like alias : 'proxy.mycompanydirect' then your store will have a proxy type 'mycompanydirect'

Related

Postman Object hasOwnProperty Tests

I am trying to evaluate a JSON, so that I can know if the properties are correct, I have the following code:
var data = JSON.parse(responseBody);
Object.keys(data).forEach(key => {
if(data.hasOwnProperty(key)){
console.log("Have all properties");
}
});
The problem I have is that, the answer is shown to me "n" times, how can I make it show it to me only once after evaluating that the properties exist?
This should do it:
var data = JSON.parse(responseBody);
let hasProperties = true;
Object.keys(data).forEach(key => {
if!(data.hasOwnProperty(key)){
hasProperties = false;
}
});
if (hasProperties) {
console.log("Have all properties");
}

How do I verify a json object loaded into a typescript class is correct?

I want to make sure the JSON I load to my typescript classes is valid.
Also, my classes have some logic, so I want want them to remain classes and not become interfaces.
I also need type checks and required/not required checks.
Right now I just load an object to my constructor and manually check each field.
Is there a way to do it by using the type information from typescript?
I tried looking at the generated javascript files but it's just javascript and the type information is already gone there.
Perhaps there's a way to use it in compile time? at that time, typescript knows the type.
I found a few libraries that do it, but none of them deals with the type of the property as well as required or not.
class MyObject {
constructor(json: any) {
if (typeof json.id == 'number') {
this.id = json.id;
} else {
throw new Error('ID is required');
}
if (json.name != undefined) {
if (typeof json.name == 'string') {
this.name = json.name;
} else {
throw new Error('Name exists, but it is not a string!');
}
}
}
id: number; // required
name?: string; // optional
}
try {
let m1: MyObject = {
id: 123
}; // works but m1 is not a class
let isMyObject = m1 instanceof MyObject ? '' : 'not ';
console.log(`m1 is ${isMyObject}instance of MyObject`);
let m2 = new MyObject({
"id": 123
});
let m3 = new MyObject({
"id": 123,
"name": "Mickey"
});
let m4 = new MyObject({
// this will throw an error
});
console.log('OK!');
} catch (error) {
console.log("Error: " + error.message);
}

Angular 5+ consume data from asp.net core web api

I have a problem consuming data from an ASP.NET Core 2.0 Web API with Angular 5+.
Here the steps i have done:
I have built an ASP.NET Core 2.0 WebAPI and deployed it on a server. I can consume data from postman or swagger without any problems.
Then i have created with NSwagStudio the client TypeScript service classes for my angular frontend app.
Now the problem:
I can make a request to the wep api from the frontend app and i am also recieveing the correct data in JSON-Format.
But while the mapping process to the poco object in the generated client service class, something doesnt work. I always get an object with empty attributes.
Here my code:
product.service.ts
export class ProductService {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: (key: string, value: any) => any = undefined;
constructor() {
this.http = <any>window;
this.baseUrl = "http://testweb01/FurnitureContractWebAPI";
}
getByProductId(productId: string): Promise<Product[]> {
let url_ = this.baseUrl + "/api/Product/GetById?";
if (productId === undefined)
throw new Error("The parameter 'productId' must be defined.");
else
url_ += "productId=" + encodeURIComponent("" + productId) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "GET",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetByProductId(_response);
});
}
protected processGetByProductId(response: Response): Promise<Product[]> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
if (resultData200 && resultData200.constructor === Array) {
result200 = [];
for (let item of resultData200) {
var x = Product.fromJS(item);
//console.log(x);
result200.push(Product.fromJS(item));
}
}
//console.log(result200);
return result200;
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<Product[]>(<any>null);
}
And here the methods from the Product-class:
init(data?: any) {
console.log(data);
if (data) {
this.productId = data["ProductId"];
this.productNameDe = data["ProductNameDe"];
this.productNameFr = data["ProductNameFr"];
this.productNameIt = data["ProductNameIt"];
this.supplierProductId = data["SupplierProductId"];
this.supplierProductVarId = data["SupplierProductVarId"];
this.supplierProductVarName = data["SupplierProductVarName"];
this.supplierId = data["SupplierId"];
this.supplierName = data["SupplierName"];
this.additionalText = data["AdditionalText"];
this.installationCost = data["InstallationCost"];
this.deliveryCost = data["DeliveryCost"];
this.sectionId = data["SectionId"];
this.categorieId = data["CategorieId"];
this.price = data["Price"];
this.ean = data["Ean"];
this.brand = data["Brand"];
this.modifiedDate = data["ModifiedDate"] ? new Date(data["ModifiedDate"].toString()) : <any>undefined;
this.categorie = data["Categorie"] ? ProductCategory.fromJS(data["Categorie"]) : <any>undefined;
this.section = data["Section"] ? ProductSection.fromJS(data["Section"]) : <any>undefined;
}
}
static fromJS(data: any): Product {
data = typeof data === 'object' ? data : {};
let result = new Product();
result.init(data);
return result;
}
In the init() method when i look at data, it contains all the values i need. But when i for example use data["ProductId"] the value is null/undefined.
Can anyone please help?
Thanks
Here is a screenshot of my console output of the data object:
enter image description here
Now I could figure out, that i can cast the data object directly to Product:
init(data?: any) {
var p = <Product>data;
This works, but i am asking myself, why does the generated class have an init-method with manually setting of the attributes, when it is possible to cast the object directly?
NSwag is misconfigured, use DefaultPropertyNameHandling: CamelCase for ASP.NET Core
Or use the new asp.net core api explorer based swagger generator which automatically detects the contract resolver. (Experimental)

webpack : is there a good hook / custom function to dump out resolved configuration?

I'm somewhat of a newbie with webpack and have been experimenting with easier ways to adjust/merge webpack configurations.
The following code, added to webpack/lib/webpack.js has been pretty helpful:
this is the standard webpack.js:
function webpack(options, callback) {
var compiler;
if(Array.isArray(options)) {
compiler = new MultiCompiler(options.map(function(options) {
return webpack(options);
}));
} else if(typeof options === "object") {
new WebpackOptionsDefaulter().process(options);
compiler = new Compiler();
compiler.options = options;
compiler.options = new WebpackOptionsApply().process(options, compiler);
new NodeEnvironmentPlugin().apply(compiler);
compiler.applyPlugins("environment");
compiler.applyPlugins("after-environment");
} else {
throw new Error("Invalid argument: options");
}
if(callback) {
if(typeof callback !== "function") throw new Error("Invalid argument: callback");
if(options.watch === true || (Array.isArray(options) &&
options.some(function(o) {
return o.watch;
}))) {
var watchOptions = (!Array.isArray(options) ? options : options[0]).watchOptions || {};
// TODO remove this in next major version
var watchDelay = (!Array.isArray(options) ? options : options[0]).watchDelay;
if(watchDelay) {
console.warn("options.watchDelay is deprecated: Use 'options.watchOptions.aggregateTimeout' instead");
watchOptions.aggregateTimeout = watchDelay;
}
return compiler.watch(watchOptions, callback);
}
compiler.run(callback);
}
this is my code:
//customization start
fs = require('fs');
var fnp_dump = 'webpack.dump.json';
fs.writeFile(fnp_dump, JSON.stringify(options, null, 2), function(err) {
if(err) {
return console.log(err);
}
console.log("dumping dump.webpack.js.final.json from webpack.js to: " + fnp_dump);
});
//customization end
return compiler;
}
The basic idea is that it dumps out the final json/js options object after webpack has finished sorting out the usual webpack.base.js + webpack.development.js. Since it's, at that point, just a fully-resolved javascript object, it doesn't really matter how the config.js files were written by individual developers.
Now you can diff options sent to webpack (this is an example of tranforming webpack 1 to webpack 2 configurations:
diff 003/webpack.dump.json 004/webpack.dump.json
< "loader": "style!css!postcss-loader!sass"
---
> "use": [
> {
> "loader": "style-loader"
> },
> {
> "loader": "postcss-loader"
> },
> {
> "loader": "sass-loader"
> }
> ]
However, I am customizing webpack.js directly and need to re-apply my patch after each npm update webpack. Is there a better way?
If your webpack.config.js is a function, you can call it on your own to resolve to an object.
If you have several configs (you mentioned webpack.base.js and webpack.development.js) you can use Webpack Merge to just combine your options to a single object, and then write it to the file system.
I would recommend you to have an own script in package.json to do this job, which you can then always call after your webpack job:
...,
"scripts": {
"dump-options": "scriptThatMergesConfigsAndWritesToFS.js",
"webpack-job": "webpack ... && npm run dump-options",
...
},
...
UPDATE
After some more research I realized, that the resolved options object is stored in the compiler object. The compiler object is passed to Plugins, and therefore you can easily write a Plugin that writes the config to a file, as I did here (not tested).
I also realized, that the Plugins cannot be stringified, as they are functions, so be aware of losing the Plugin configuration information.
I ended up writing my own plugin (and now notice that wtho wrote one too). It worked for me - note you need to have the bit of code that handles circular references:
// WebPackCompilationObserver.js
function WebPackCompilationObserver(options) {
WebPackCompilationObserver.options = options || {};
}
WebPackCompilationObserver.prototype.apply = function(compiler) {
compiler.plugin("emit", function(compilation, callback) {
var fs = require('fs');
var fnp_dump = WebPackCompilationObserver.options.dump_filename;
if (! fnp_dump) {
fnp_dump = "./dump.webpack.options.json";
console.log("please specify dump_filename path in the WebPackCompilationObserver.options, otherwise using default:" % fnp_dump);
}
if (fnp_dump){
console.log("dumping compilation.options to: " + fnp_dump);
var cache = [];
fs.writeFile(fnp_dump, JSON.stringify(compilation.options, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
}, 2),
function(err) {
if (err) {
return console.log(err);
}
});
cache = null;
}
callback();
});
};
module.exports = WebPackCompilationObserver;
To use it:
webpack.config.development.js:
....
var WebPackCompilationObserver = require("./WebPackCompilationObserver");
....
config.plugins = config.plugins.concat([
....
,new WebPackCompilationObserver({dump_filename: '../dumpithere.json'})
])

Define json specific field is declared or not

I have Asp.Net Mvc4 application. In one Action method I have conditional process that return different json result as follows:
if(true)
{
return Json(new { count = cartItm.ProductCount, total = cartItm.TotalAmount });
}
else
{
return Json(new
{
thumb = item.ThumbnailPhoto,
productName = item.Name,
itemCount = cartItem.ProductCount,
itemTotal = cartItem.TotalAmount,
productTotal = cart.TotalAmount,
productCount = cart.CartItems.Sum(items=>items.ProductCount)
});
}
In jquery click event I can't define which json is returned. I write if condition as follows but get wrong result.
success: function (data) {
if (data.thumb != null) {//some operations }
else{//some operations }
Perhaps it is very easy problem, but I am new with json. Please help me.
thanks for reply
Check for "undefined" instead
success: function (data) {
if (typeof data.thumb !== "undefined") {//some operations }
else{//some operations }
Because item.ThumbnailPhoto on your server may be null. If this is the case, your check will fail.
Try this,
success: function (data) {
if (data && data.thumb) {//some operations }
else{//some operations }
}
The problem might be because you don't have data.thumbs in your first json, in your Action,
if(true)
{
return Json(new { flag = 1, count = cartItm.ProductCount, total = cartItm.TotalAmount });
}
else
{
return Json(new
{
flag = 2,
thumb = item.ThumbnailPhoto,
productName = item.Name,
itemCount = cartItem.ProductCount,
itemTotal = cartItem.TotalAmount,
productTotal = cart.TotalAmount,
productCount = cart.CartItems.Sum(items=>items.ProductCount)
});
}
in your view :
success: function (data) {
if (data.flag == 1) {//some operations }
elseif (data.flag == 2) {//some operations }
didnt check the code, but this must work.