Variable in javascript file not accessible in object property - javascript

I have the following problem. I have a JS-file which has a handful of variables. Those I initialize in a function:
var currentYear;
var previousYear;
var urlQuarterDates;
var urlHalfYear;
var urlYear;
var urlMonth;
var urlProposalsSentAndReceived; //= '/Marketing/ListProposalsSentAndReceived';
var urlProposalsResponsibleMonth;
function initTabReportProposalsMonth(_currentYear, _previousYear, _urlViewProposal,
_urlQuarterDates, _urlHalfYear, _urlYear, _urlMonth, _urlProposalsSentAndReceived,
_urlProposalsResponsibleMonth) {
currentYear = _currentYear;
previousYear = _previousYear;
urlQuarterDates = _urlQuarterDates;
urlHalfYear = _urlHalfYear;
urlYear = _urlYear;
urlMonth = _urlMonth;
urlProposalsSentAndReceived = _urlProposalsSentAndReceived;
urlProposalsResponsibleMonth = _urlProposalsResponsibleMonth;
}
I have defined an event handler in the same JS-file:
function onPeriodSelect(combo, rec, i) {
var conn = new Ext.data.Connection();
var params = { };
switch(rec.get('myId'))
{
case _currentQuarter1:
conn.url = urlQuarterDates;
params.y = currentYear;
params.index = 1;
break;
}
reload(); //
}
The variables urlQuarterDates and currentYear are readily accessible. So far, so good...
I also have an ExtJs Grid with a data store which is declared inline:
var gridSentAndReceived = new Ext.grid.GridPanel({
title: 'Totaal',
autoHeight: true,
autoWidth: true,
store: new Ext.data.Store({
id: 'idStoreSentAndReceived',
proxy: new Ext.data.HttpProxy({ url: urlProposalsSentAndReceived,
timeout: 1800000 }),
reader: new Ext.data.JsonReader(
{
root: 'rows'
},
[
{ name: 'Status' },
{ name: 'nrOfProposals' },
{ name: 'TotalRevenueHardware' },
{ name: 'TotalRevenueYearly' },
{ name: 'TotalRevenueHours' }
]),
remoteSort: false
}),
frame: true,
iconCls: 'icon-grid',
columns: [
...
],
viewConfig: {
forceFit: true
}
});
The reload() function calls the load of the store of gridSentAndReceived. This generates an exception: the url is not defined at all. If I initialize the url right at its declaration (which is currently commented out' it works fine. When I browse using the debugger it shows that urlProposalsSentAndReceived is initialized. Still, it claims there is no URL.
This seems to be a scope problem, since variables are accessible from the event handler but obviously not elsewhere. Anybody knows how to fix it? The URLs are created using server tags and those cannot be put in JS files. I wouldn't enjoy putting them directly in the JS file as a text string. Is there a possible solution?
Update
I have tried a few more things but nothing works.
I have tried:
'beforeload': function (store, options) {
store.proxy.setUrl('/Marketing/ListProposalsSentAndReceived');
}
but even that didn't work. Still got the same exception. I really have no clue why that failed though, I took the code from the ExtJs Documentation under 'api'.
Now I have no choice but hardcoding the urls in my js-file though I'd very much prefer to use servertags and add them dynamically. Hopefully, one day, I'll find a solution rather than getting runtime errors when I change the location of a controller action.

This is not a scope issue. At the time you run your code urlProposalsSentAndReceived is not defined. If you set that variable via an event handler, the value is always set after gridSentAndReceived is initialized.

Related

Vue app (data out of scope) - Data is not defined at Proxy.calc

*Greetings Stackoverflow peeps.
I am developing my first Vue app and having issues with using the find function to loop through my metals list to pull the specificGravity value based on a matching type prop.
It seems that the list is out of scope and I am unable to find a solution through good ole' Google, so I turn to you all.
TIA*
Error:
"vue#next:1751 Uncaught ReferenceError: data is not defined
at Proxy.calc (index.html:101:45)
at onClick (eval at compileToFunction (vue#next:15591:23), :142:35)
at callWithErrorHandling (vue#next:1688:24)
at callWithAsyncErrorHandling (vue#next:1697:23)
at HTMLButtonElement.invoker (vue#next:9486:15)"
<script>
var app = Vue.createApp({
data: function() {
return {
waxWeight: null,
isVisible: true,
buttonSize: null,
specificGravity: null,
metalType: null
}
},
// <!-- COMPONENTS -->
components: {
},
// <!-- METHODS -->
// `this` inside methods point to the current Vue instance
methods: {
calc: function (waxWeight, buttonSize, metalType) {
var waxWeight = waxWeight
var buttonSize = buttonSize
var metalType = metalType
var metals = {metals:[
{ type: 'silver', specificGravity: 10.3 },
{ type: 'wGold14', specificGravity: 12.1 },
{ type: 'wGold18', specificGravity: 11.5 },
{ type: 'yGold14', specificGravity: 13.6 }]}
// method does not have access to data list
const specificGravity = data.metals.find(function(elem){
if(elem.name == metalType)
return elem.specificGravity;
alert(metalType)
});
}
},
})
app.mount('#app')
</script>
i'm not sure what you are trying to do in this function, but I will try to help you.
The problem is data is not accessible like that, data is a function that return a JSON object. So imagine you want to access the isVisible declared in the Data. You use this.isVisible.
However I can't understand why you need to access data there. It seems that you want to access the array inside the json object, so try metals.metals.find(...). And if you want to access the array metals, when you are calling elem.name you are always going to get undefined since this is not a key of the object, you should use elem.type instead. Here is a code pen that I made for you to exemplify what I'm saying
Sorry for the long answer, if this not help you please provide more context so I can help you
Initial issue resolved here: https://codepen.io/pandemicprogrammer/pen/GROWqwR
I was referencing the array object incorrectly and had my JSON data in the wrong spot.
methods: {
calc: function (waxWeight, buttonSize, metalType) {
alert("test")
var waxWeight = waxWeight
var buttonSize = buttonSize
var metalType = metalType
var metals = {metals:[
{ type: 'silver', specificGravity: 10.3 },
{ type: 'wGold14', specificGravity: 12.1 },
{ type: 'wGold18', specificGravity: 11.5 },
{ type: 'yGold14', specificGravity: 13.6 }]}
const specificGravity =
metals.metals.find(function(elem){
if(elem.type == metalType) {
alert(elem.specificGravity)
return elem.specificGravity;
}
});
}
},

Creation of a global, persistent object into Extjs

Good day all.
I'm into a big project that uses EXTjs (i guess it's 4.0), the project is huge and have several years behind.
I'm not into Extjs so I'm trying to learn what to do and how to do it, and my new task is to create a persistent, global object, available into the whole application in which I need to store some information that are used in different parts of the project (let's say for example that the user can set a particular property of this object to "true" while doing some actions and this "true" it will be used into another viewcontroller to enable some functions, things like this).
so, I've created a new file called userJsonMainModel.js :
Ext.define('Tac3.userJsonMainModel', {
extend: 'Ext.data.Model',
constructor: function() {
var userJsonMainModel = this;
userJsonMainModel.callParent(arguments);
userJsonMainModel.data.tmp = {};
},
testProperty:{foo:"bar"},
testMethod: function (){
console.log("testFunction called");
}
});
and in Application.js :
requires: [
...
'Tac.userJsonMainModel'
],
stores: ['Countries', 'Kpis', 'Dimensions'],
autoCreateViewport: false,
init: function() {
var controller = this
Ext.tip.QuickTipManager.init();
Ext.setGlyphFontFamily('FontAwesome');
var userJsonMainModel = controller.createUserJsonMainModel();
console.log("into init: ", this.userJsonMainModel.testProperty);
...
createUserJsonMainModel: function() {
var controller = this;
controller.userJsonMainModel = Ext.create('Tac3.userJsonMainModel', {
controller: controller
});
console.log("check if the jsonmainmodel exist ",controller.userJsonMainModel.testProperty);
},
this is actually working, now the second step is to access the same object from another view (or its viewcontroller), this is what I've done into a a viewController:
Ext.define('Tac3.view.udesign.UdesignController', {
extend: 'Ext.app.ViewController',
alias: 'controller.udesign',
init: function(view) {
...
console.log("into init: ", this.userJsonMainModel.testProperty);
}
and this is actually throwing a:
Uncaught TypeError: Cannot read property 'testProperty' of undefined
I was pretty sure the objects defined into application.js would be globally accessible, but I guess I'm wrong, or doing something in a wrong way.
since I've found quite no examples on this topic (which is probably because it is not a standard way to do this), I'd like to ask what I'm doing wrong?
Just define a class and require it in your application:
Ext.define('MyApp.Globals', {
singleton: true,
foo: 100,
bar: 'baz'
});

Angular - how to do a dynamic alert with different type of errors?

In my web app I am showing alerts for loading content and another alert when there is an error.
I am using AngularJS/AngularStrap
right now this is what I have:
var noLinesAlert = $alert({
title: 'Sorry, no lines at this moment :(',
container: '.no-lines-alert',
type: 'danger',
dismissable: false,
show: false
}),
loaderAlert = $alert({
content: 'Loading content. Please wait...',
container: '.alerts-container',
type: 'info',
show: true
});
and I am calling these alerts this way, example noLinesAlert.show() or loaderAlert.hide() and so on... but just imagine that I will have 4 more alerts for special cases, do I have to create those vars with the object inside every time or is there a way to do it more programmatically? and how.
Well, you can store "default" settings for those 4 special cases in dedicated object, for example: ALERTS_SETTINGS = { notice: {} }, and then the call would be much more concise:
var noticeOptions = angular.extend(ALERTS_SETTINGS.notice, { title: "My custom property one" })
var notice = $alert(noticeOptions)
Using angular.extend you can override any default setting from the original object by those you provide in the second argument.
For every alert the title, container, type, and show property changes. You need to give the program that information, so you can't do this any shorter.
Make it dynamic by putting the $alert into a function. Allow the function to pass parameters to the $alert. Set the show property to true.
Call the function when needed. For example:
var displayAlert = function(alertTitle, className) {
var alertOptions = {
title: alertTitle,
container: className,
type: 'danger',
dismissable: false,
show: true
};
var alert = $alert(alertOptions);
}
// Call the function when needed
$scope.displayAlert('Sorry, no lines at this moment :(','.no-lines-alert')

When is "is_initial" true in Dygraph's drawCallback?

I have a Dygraphs chart that works perfectly when I provide a file URL for a data source. When I embedded the data directly into the HTML wrapper, however, the functions in my drawCallback don't fire. Tracing with Firebug, I find that is_initial is True when I load the page with the URL reference, but False when I embed the data (and labels) in native format, even if I place onLoad="drawCallback(vGraph,True);" within the <body> tag. I've "solved" this by setting my own variable to test for first-time execution.
Here's the original, functional, code for an external data source:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
}
});
As I said, this works great, even with the blind g parameter in the drawCallback.
This is the work-around I developed for the scenario when I embed the data source.
var vFirstTime = true;
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
[
[ new Date("2011/10/15 00:04:55"),null,null,-9.2,null,null,null,null,null,null],
[ new Date("2011/10/24 10:39:32"),null,null,null,null,null,-9.2,null,null,null],
...
[ new Date("2011/10/25 21:02:30"),null,null,null,null,null,null,null,20.3,null],
[ new Date("2013/10/28 08:49:52"),null,null,-17.9,null,null,null,null,null,null]
],
{ //options
labels: ["Event_Date","code-32565","code-32566","code-32568","code-32569","code-32573","code-32574","code-32575","code-32577","code-32578"],
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
// drawCallback: function(g, is_initial) {
// if (!is_initial) return;
drawCallback: function() {
if (!vFirstTime) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
vFirstTime=false;
}
});
Is there something I can do to use is_initial in my drawCallback call regardless of the data source?
Your first example will work if you move your callbacks into the constructor:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
},
...
});
So, what's going on here?
The drawCallback gets fired with is_initial = true when the chart draws for the first time. In your original code, this happens after the XMLHttpRequest for the data comes back.
The order of operations is:
constructor
updateOptions
drawCallback(is_initial=true)
When you inline your data, dygraphs doesn't need to wait for the XHR to come back. Now, the order of operations is:
constructor
drawCallback(is_initial=true)
updateOptions
drawCallback(is_initial=false)
The second drawCallback happens because you called updateOptions(). So drawCallback is getting fired with is_initial = true, it's just that you're not listening for it early enough.
dygraphs provides a .ready() method to let you avoid all this intricacy. You may be happier using it instead:
var vGraph = new Dygraph( ... );
vGraph.ready(function() {
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
});

Accessing Ext Designer JsonStore from another file

I want to access an JsonStore created from the ext designer from another panels user js file.
The file store file generated from the designer looks like this
myJsonStore = Ext.extend(Ext.data.JsonStore, {
constructor: function(cfg) {
cfg = cfg || {};
CoaJsonStore.superclass.constructor.call(this, Ext.apply({
storeId: 'myJsonStore',
url: '/server.json',
restful: true,
autoLoad: true,
autoSave: false,
fields: [
{
name: 'id'
},
{
name: 'code'
},
{
name: 'name'
}
]
}, cfg));
}
});
new myJsonStore();
what i am doing right now is using a hidden combo and assign the store to the combo, this allows me to access it via autoRef (with. combo.getStore(), it gives me an object type of Store). Ideally i want to be able to do it without the hidden combo.
i have tried referring to it with storeId, but it doesn't work, if i log the storeId to the console this is what i get.
function (cfg) {
cfg = cfg || {};
CoaJsonStore.superclass.constructor.call(this, Ext.apply({
storeId: 'myJsonStore',
url: '/coas.json',
restful: true,
........
so i was just wondering whether this is even possible. if so some direction on how to get it done would be greatly appreciated . thanks
The new myJsonStore(); only creates a new store. In order to reference the store elsewhere in your code ( same file or another file) you need to use a variable. Create the store like this:
var myStore = new myJsonStore();
And to bind it to the comobobox use the variable name myStore with the store property.

Categories

Resources