PDA

View Full Version : Dynamic url Store



saandrango
2 Feb 2017, 5:30 AM
Hello all.

In our company we are starting to develop applications based exclusively on Sencha Architect. We work with two environments, one of development and one of production. The two environments consist of a web server and a database server of their own. We want to use a variable that points directly to the web server that interacts with the database depending on the environment. We have declared a BASE_URL variable with the address of our web server in the application configuration, like this:



// @require @packageOverrides
Ext.Loader.setConfig ({
});
Ext.application ({
BASE_URL: 'http://developmentserver/php/app/,
Models: [...],
Stores: [...],
Views: [...],
Name: 'AppName',
Launch: function () {
Ext.create ('AppName'.view.main.Main');
}
});



Our question is: How can we declare the url property in a Store that points to this BASE_URL variable, if it was generated by the Data UI Builder and the code generated by Sencha Architect is not editable?


The Store should look like this:



Ext.define ('AppName.store.ResourceStore', {
Extend: 'Ext.data.Store',
Alias: 'store.recursostore',


Requires:
'AppName.model.ModelResource',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],


Constructor: function (cfg) {
Var me = this;
Cfg = cfg || {};
Me.callParent ([Ext.apply ({
GroupField: 'resource_id',
StoreId: 'ResourceStore',
AutoLoad: true,
Model: 'AppName.model.ModelResource',
Proxy: {
Type: 'ajax',
Url: BASE_URL + 'AppName/resource',
Reader: {
Type: 'json',
rootProperty: 'data'
}
}
}, Cfg)]);
}
});



Thanks for your help

Santiago

petr.vecera
2 Feb 2017, 7:08 AM
Hi

You can use process config on the proxy and set-up the URL manually. Problem is that the editing using process config will not probably load your store correctly on the design view (inside SA). But it will work in browser preview and the final app.

Check this how to use process config:
http://recordit.co/kYeDuahbVd (http://recordit.co/J3TAvGw5i6)


The url config is bindable, you could bind it and specify the url in the view-model.

http://docs.sencha.com/extjs/6.2.1/classic/Ext.data.proxy.Server.html#cfg-url

Regards
Petr

//Edit: I Have made mistake in the first video, I have updated the video with correct steps.

saandrango
2 Feb 2017, 8:19 AM
Thanks Petr.


I have tried the first option and the application does not load. The error that appears is: ReferenceError: BASE_URL is not defined.


When I am working with a button and want to interact with the database, I use the following in the button programming:



url: AppName.app.BASE_URL + 'Appname/resource/save'


And works correctly.


But putting the same in processMyAjaxProxy, another error appears: TypeError: AppName.app is undefined


The second option I'm going to study, because I'm new to ExtJS and Sencha Architect.

Santiago

ssamayoa
4 Feb 2017, 1:17 PM
1. Create a singleton class to store constants such BASE_URL
(Remember to define alternateClassName else you will need to use full class name to access data stored there)



Ext.define('T1.store.Constants', {
extend: 'Ext.Base',

alternateClassName: [
'Constants'
],
singleton: true,


BASE_URL: 'http://something/'
});


2. Override Ajax and/or Rest proxy's buildUrl, ex:



Ext.define('T1.override.data.proxy.Ajax', {
override: 'Ext.data.proxy.Ajax',

buildUrl: function(request) {
return Constants.BASE_URL + this.callParent();
}

});


To do so find the Ajax or Rest proxy in the component palette > right click > "Create Override for this class"

3. Add your constant's class to required clause on application:



// @require @packageOverrides
Ext.Loader.setConfig({


});




Ext.application({


requires: [
'T1.store.Constants'
],
views: [
'MyPanel'
],
name: 'T1',


requires: [
'T1.store.Constants'
],


launch: function() {
//....
}


});


Regards!

saandrango
8 Feb 2017, 12:35 PM
Thank you ssamayoa. My computer was damaged and I will just deal with this solution.
Santiago

saandrango
10 Feb 2017, 8:27 AM
Hello again. Thanks for helping, but I have a new error. I followed all the steps:

I have created a singleton class with the variable BASE_URL:


Ext.define('CV.store.Constantes', {
extend: 'Ext.Base',
alternateClassName: [
'Constantes'
],
singleton: true,
BASE_URL: 'http://localhost/servidor/cv/datos_generales/datos_etnia'
});



I override the buildUrl (Ajax.js)


Ext.define('CV.override.data.proxy.Ajax', {
override: 'Ext.data.proxy.Ajax',
buildUrl: function(request) {
return Constantes.BASE_URL + this.callParent();
}
});


I have placed in the requires of the Application


// @require @packageOverrides
Ext.Loader.setConfig({
});
Ext.application({
requires: [
'CV.store.Constantes'
],
models: [
...
'EtniaModel'
],
stores: [
...
'EtniaStore'
],
views: [
...
],
name: 'CV',
requires: [
'CV.store.Constantes'
],
launch: function() {
...
}
});


And I configured it in the proxy set-up



Ext.define('CV.store.EtniaStore', {
extend: 'Ext.data.Store',

requires: [
'CV.model.EtniaModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'EtniaStore',
autoLoad: true,
model: 'CV.model.EtniaModel',
proxy: me.processMyAjaxProxy({
type: 'ajax',
reader: {
type: 'json',
rootProperty: 'data'
}
})
}, cfg)]);
},

processMyAjaxProxy: function(config) {
url = CV.store.Constantes.BASE_URL;
return config;
}
});


But I have the following error: {msg: "You are using ServerProxy but have not supplied it with a url.", SourceMethod: "buildUrl", sourceClass: "Ext.data.proxy.Server"}

Am I wrong in anything?
Thanks for the help
Santiago

bogc
8 Nov 2017, 1:05 PM
Petr, I am interested in this thread as well. Could you please provide a sample or show how one would use the binding in this case in SA? I understand how the binding works between view models and views but in this case the store and its associated proxy could be associated with the Application object directly (i.e. added to the Application stores collection). In that case how would the binding work? If the store is defined in the ViewModel then it's all ok, formulas can be used to prepend the URL prefix.

In my mind this could have been solved easily if the proxy Url was editable as an expression instead of a string. Then you could assign it an expression.

Just a comment on the other solutions - it seems to me that they lead to a lot of work - you have to override processConfig or create overrides and so on, you have to repeat this all over the place for each proxy. In my mind it is not a good approach.

Thanks

petr.vecera
8 Nov 2017, 4:18 PM
Yeah, this totally sucks in SA. We wanted to do something about it, I think there might be some request ticket laying around. Basically what you can do with VM isn't anything fancy. Something like this:


Ext.define('MyApp.view.MyPanelViewModel', { extend: 'Ext.app.ViewModel',
alias: 'viewmodel.mypanel',


requires: [
'Ext.data.Store',
'Ext.data.proxy.Ajax',
'Ext.data.field.Field'
],


data: {
something: 'http://www.google.com'
},


stores: {
hello: {
autoLoad: true,
proxy: {
type: 'ajax',
url: '{something}'
},
fields: [
{
name: 'one'
},
{
name: 'two'
},
{
name: 'three'
}
]
}
}


});

But than if you have more viewmodels you would need to have some function in the launch function or somewhere which would get all the VM from the app and set the url data field :|

Also if you will use this kind of dynamic url it will not in the SA Design view. It will most likely print an error http://prntscr.com/h81242 but in the browser it should work

-----------------------------

Hm I just got another idea, what about creating one view model, define the url in the data field, just that - nothing more and than let all the other viewmodels extend from that. Hm maybe it could work, but I am going to bed ...

GL

petr.vecera
8 Nov 2017, 4:20 PM
Jeez just got popup that my message I posted in here was put for the moderator review ... I hope that someone will do that ... lol

bogc
8 Nov 2017, 8:53 PM
@saandrango (https://www.sencha.com/forum/member.php?812371-saandrango): I know it's a very late answer and probably the code is not relevant anymore. I think the mistake is in the line:


url = CV.store.Constantes.BASE_URL;

It should have been imo:

config.url = CV.store.Constantes.BASE_URL + "/some/other/path";

bogc
8 Nov 2017, 8:56 PM
@saandrango (https://www.sencha.com/forum/member.php?812371-saandrango): I know it's a very late answer and probably the code is not relevant anymore. I think the mistake is in the line:


url = CV.store.Constantes.BASE_URL;

It should have been imo:

config.url = CV.store.Constantes.BASE_URL + "/some/other/path";

Having said that, I don't think it was necessary to override processConfig for the proxy because the buildUrl of the ajax proxy class was overridden (I haven't tested but I assumed ssamayoa (https://www.sencha.com/forum/member.php?146904-ssamayoa)'s answer was correct), so I think you only needed to assign the relative url in the proxy config and that was it.

EricRicher
10 Nov 2017, 7:53 AM
I just started a thread related to this in the ExtJS forum before I stumbled on this one.

I also use Architect and have a dev and prod environment. I use Process Config to set the url of proxies to point to either a dev or a prod server. However, I use the build environment to define a base url that ends in the Ext.manifest and it works well.

I added the following to the app.json:



"production": {
"baseurl": "https://www.enofily.com/api"
},
"testing": {
"baseurl": "https://www.enofily.com/api"
},
"development": {
"baseurl": "/api"
}


The "baseurl" ends up in the manifest as Ext.manifest.baseurl and I use it like this in any Process Config functions in Architect:



processMyRestProxy: function(config) {
config.url = Ext.manifest.baseurl+config.url;
return config;
}


However, one issue that I am having with this method is that not all classes in Architect have Process Config and the most notable is the data.model class where I can't do this for the model's proxy config. Hence my other thread to see what other people are doing.

If Architect allowed the user to set the url config to something else than a string, one could enter directly Ext.manifest.baseurl+'/path/to/service' directly in the config pane. Maybe that could be an improvement to Architect.