Controller Stuck at component.get("v.recordId") - salesforce

I am trying to get case record Id using lightning button but my controller is not moving forward from this line -component.get("v.recordId")
I don't know what is wrong.
Please help:
This my component
<aura:component controller="EmailSendController" implements="flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global">
<lightning:button label="Send Notification" title="Send Notification" onclick="{!c.sendMail}"/>
This is my controller
({
sendMail: function(component, event, helper) {
console.log("Button Clicked--");
var caseID = component.get("v.recordId");
Console.log("CaseID--"+ component.get("v.recordId") );
var action = component.get("c.sendMailMethod");
action.setParams({
"caseId" : caseID
});
action.setCallback(this, function(response) {
var state = response.getState();
Console.log("Response"+response.getState());
if (state === "SUCCESS") {
//var storeResponse = response.getReturnValue();
}
});
$A.enqueueAction(action);
},
})

JavaScript is case-sensitive. 2nd Console should be lowercase, I suspect it throws an error about undefined object.
You can use your browsers JS console (in Chrome Ctrl+Shift+J) to inspect such errors. It also helps to go to Setup -> Debug Mode and add your user in there. SF will get bit slower but you'll see more human-readable code and errors instead of optimised, minified mess.
If it still throws errors - use console to check what error exactly and edit your question?
P.S. change it in callback handler too

Related

'Dashboard not a constructor' error with Google Charts

I am a naive React Developer and facing some difficulty with getting gooogle chart work with react. I am using Google Charts in a ReactJs component with ControlWrapper as shown below.
componentDidMount: function(){
google.charts.load('current', {'packages':['corechart', 'controls']});
this.drawCharts();
},
componentDidUpdate: function(){
google.charts.load('current', {'packages':['corechart', 'controls']});
this.drawCharts();
},
drawCharts: function(){
var cmpt = this;
//Removed detailed code from here due to copyright issues
//adding controls----------------
let dashboard = new google.visualization.Dashboard( document.getElementById(cmpt.props.widgetId) );
let controlId = '${this.props.widgetId}_control';
var controlWrapper = new google.visualization.ControlWrapper({
'controlType' : 'NumberRangeFilter',
'containerId' : controlId,
'options' : {
'filterColumnLabel' : xDataSysName
}
});
var barChart = new google.visualization.ChartWrapper({
'chartType': 'BarChart',
'containerId': this.props.widgetId,
'options': options
});
dashboard.bind(controlWrapper, barChart);
dashboard.draw(data);
if(linkColumn){
let selectionEventHandler = function() {
window.location = data.getValue(barChart.getSelection()[0]['row'], 1 );
};
google.visualization.events.addListener(barChart, 'select', selectionEventHandler);
}
}
},
This is not the whole piece of code but should be enough for the issue I'm facing.
First time I load the page, I get the error in the console saying
google.visualization.Dashboard is not a constructor
I reload the page hitting SHIFT+F5, the error goes away and components load just fine except ones that are dependent on controlWrapper throwing the error as follows
google.visualization.controlWrapper is not a constructor
which never goes away even after reloading the page. I referred to this discussion and tried their solution but I am still getting these error in the manner mentioned above. Please help me figure out how to fix it. Also, I am not able to comprehend why dashboard error goes away on a reload.
need to wait until google charts has fully loaded before trying to use any constructors,
this is done by providing a callback function.
try changing the load statement as follows...
componentDidMount: function(){
google.charts.load('current', {packages:['corechart', 'controls'], callback: this.drawCharts});
},
componentDidUpdate: function(){
google.charts.load('current', {packages:['corechart', 'controls'], callback: this.drawCharts});
},

React keep data attribute

I have to do a 'simple' task. It is actually simple if you know the react framework or have any Javascripts knowledge in particular but my Javascript knowledge is pretty terible so I am really stuck now.
What I am trying to achieve is, I have a button 'terminate' in a table (so several rows). When I click the button, I want the console log to throw me the transactionID of that row. But I really cannot get it to work. This is what I have currently:
I have a class with in it several methods, of one is a 5 sec auto refresh function:
var ExceptionalCases = React.createClass({
I created this method:
TerminateCase: function(e) {
e.preventDefault();
this.setState({
}, function() {
var transactionID = this.refs.transid.target.getAttribute("data-transid");
console.log('button clicked' + transactionID);
}.bind(this));
},
And this is the button (located in the render):
<input type="button" name="TerminateCase" value={_('Terminate')} style={{width: '110px'}}
onClick={this.TerminateCase} ref="transid" data-transid={entry.transactionId}/>
This is the error I get:
TypeError: this.refs.transid.target is undefined
I am clueless, I searched alot and tried many different approaches but I am really stuck now. I hope that someone can help me ;-(
Try this:
TerminateCase: function(e) {
e.preventDefault();
var transactionID = e.currentTarget.getAttribute("data-transid");
console.log('button clicked' + transactionID);
}

How to add a custom error page in Cordova InAppBrowser or hide the error url?

pleas check this attached image I'm building an Ionic Android app with the InAppBrowser plugin. When the internet connection is not available, the plugin shows web page not available and requesting url.
Please help me customise the InAppBrowser error page (404 page). Or help me hide the requesting url.
Thank you.
I think I misunderstood your problem, first time, sorry about that. I'm reading again your problem and I'm figuring out what's happening. You need to add a custom configuration at config.xml to redirect to an error page when Cordova detect it. I hope this solve your problem.
<preference name="ErrorUrl" value="myErrorPage.html"/>
The original response works when you want to open a link through Cordova inAppBrowser plugin. If this doesn't sort out your problem, please reformulate your question.
Original response
You could be listening inAppBrowser events to figure what's happening.
Here, you can see how listen browser events, such as loaderror and manage the 404 error as you want. You must save a reference to inAppBrowser when open method is called, and then you could listen for error event.
function loadErrorCallBack(params) {
// Do stuff
}
inAppBrowserRef = cordova.InAppBrowser.open(url, target, options);
inAppBrowserRef.addEventListener('loaderror', loadErrorCallBack);
I am using Ionic 4 and I couldn’t manage to make the solution based on config.xml editing to work :
preference name="ErrorUrl" value="myErrorPage.html"/
Placing an addEventListener on loaderror didn’t work neither. It looks like it is not triggered by http errors and the plugin need a fix.
But we found a hack that is much simpler.
On loadstop we wait 500 milliseconds and then we get the loaded url by triggering executeScript with and window.location.href
If the loaded url is of the custom error page, in Cordova (not in IAB) we display a custom message with a back button.
It's a hack but that cover the requirement for now
I just came across the same problem and here's what I did. The code is for Android and works on IOS as well. But you would want to remove navigator.app.exitApp(); for IOS as Apple does not allow apps to take exit without pressing the home button.
Let me know if this works for you. It will hide default error page and open your custom error page. Write your own error code in myerrorpage.html
document.getElementById("openBrowser").addEventListener("click", openBrowser);
document.addEventListener("offline", onOffline, false);
function onOffline(e) {
e.preventDefault();
var src = 'myErrorPage.html';
var target = '_blank';
var option = "loaction=no, toolbar=no, zoom=no, hidden=yes, hardwareback=no";
var ref = cordova.InAppBrowser.open(src, target, option);
alert('Your device is Offline. Please check your connection and try again.');
navigator.app.exitApp();
}
function openBrowser() {
var url = 'https://www.yourlink.com';
var target = '_self';
var options = "location=no,toolbar=no,zoom=no, hardwareback=no, hidden=yes" ;
var ref = cordova.InAppBrowser.open(url, target, options);
}
When the components do not work, I perform the following procedure
ionic state reset
ionic platform remove android
ionic platform remove ios
ionic platform add android
ionic platform add ios
and try with ionicPlatform ready
<button class="button button-balanced" ng-click="OpenBrowser()">Test</button>
In controller
$scope.OpenBrowser = undefined;
$ionicPlatform.ready(function () {
$scope.OpenBrowser = function () {
$cordovaInAppBrowser.open('http://ngcordova.com', '_blank', options)
.then(function (event) {
})
.catch(function (event) {
$scope.Error = event;
});
};
});
I couldn't manage solution with setting ErrorUrl in Ionic 4 on Android to work.
Finally I came up with another solution - hide default error page and redirect user to any page (I use last page from event.url).
constructor(private iab: InAppBrowser) {
}
private openUrl(url: string)
{
this.platform.ready().then(() => {
if (this.platform.is('cordova')) {
this.openBrowser(url);
}
});
}
private openBrowser(url: string): InAppBrowserObject
{
const options: InAppBrowserOptions = {
location: 'no',
zoom: 'no',
hidden: 'no'
};
const browser = this.iab.create(url, '_blank', options);
browser.on('loaderror').subscribe(
event => this.onLoadError(event, browser)
);
return browser;
}
private onLoadError(event: InAppBrowserEvent, browser: InAppBrowserObject): void
{
browser.executeScript({
code: `
window.addEventListener('DOMContentLoaded', function () {
document.querySelector('body').style.background = 'black';
document.querySelector('body').innerHTML = '';
}, true);
window.addEventListener('load', function () {
window.location.replace('${event.url}');
}, true);
`,
}
).then();
}
Changing background and redirecting is tricky - from my experiments using injectCss won't work, because body is generated in the meantime. Using DOMContentLoader makes it black and clears text on screen.
But redirecting won't work in DOMContentLoader (don't ask me why), so you need to use load event.
It works great when user is using hardware back and returns to POST request - this way he will be redirected to GET of the same url (but you can use any url you want).

Visual Studio 2015 update3/cordova update 10 bug for apk building?

I've updated my Visual Studio to "Update 3" and the newest cordorva as of 7/7/2016, basically I applied all the updates. And it seems failed my app.
There is the following code in the html file templates\events.html.
<div class="events-2colmn-l backgnd-cover" ui-sref="menu.music">
MUSIC
</div>
In route.js
.state('menu.music', {
url: '/music',
views: {
'side-menu21': {
templateUrl: 'templates/music.html',
controller: 'musicCtrl'
}
}
})
There is a service.js file.
angular.module('app.services', ['ngResource'])
.factory('EventService', ['$resource', function ($resource) {
return $resource('https://....azurewebsites.net/api/events/:id', { id: "#id" });
}]);
And in the controller there is
.controller('musicCtrl', function ($scope, EventService) { // called twice when clicked
var allEvents = EventService.query({ category: "Music" });
allEvents.$promise.then(function (response) {
$scope.events = response; // response is undefined after updates
});
})
The parameter response is undefined when debugging using "Google Android Emulator" (Side-loading on phones got the same behaving so it should also get undefined). However, response got the right value when running in Ripple or built by Visual studio before applying the updates.
Is there any workaround?
Update:
I clicked the earliest call in "Call STack" when debugging in emulator and find the following code was called in ionic.bundle.js.
xhr.onload = function requestLoaded() {
var statusText = xhr.statusText || ''; // statusText is "Not found" but xhr is null
......
completeRequest(callback, // call stack
status, // 404
response, // ""
xhr.getAllResponseHeaders(), // xhr is null
statusText); // Not found
However the cursor on status and it shows 404. The url has the correct value of "https://....azurewebsites.net/.....".
And I tried opening a browser in emulator and I can access internet the link and got the webapi output.
Update 2:
There is one thing different between ripple and emulator. I set breakpoints as following. The ripple will break on both after click the item. However, in emulator, the first time the code will only break on the first breakpoint, continue running then break both the breakpoints.
.controller('musicCtrl', function ($scope, EventService) {
var allEvents = EventService.query({ category: "Music" }); // Emulator stops twice here
allEvents.$promise.then(
function (response) {
$scope.events = response; }, // Ripple stops here after one top break
function (e) {
console.log(e); } // Emulator stops here after two top breaks
);
})

still the navigate triggers and upate my url, the method is not calling

In my backbone app, i use the requirejs to load the js files. as well i need different views, there is no.of links are there in my drop down menu. according to the drop down menu i a adding the #url example:
http://localhost:85/bino/html/interface-I.html#projectName/project11
the navigate method works fine and updating the url, also whenever i copy and paste this url to any other browser / refresh with current hash state my router methods works fine.
But click on link in the drop down menu not working, the method not calling... what would be the reason and how can i fix this..?
my code: main js file (part of code)
var extender = _.extend({},backBone.Events);
var params ={
boardHolder :$('.boardHolder'),
column :3,
space :30,
extender :extender
};
var listApp = new routerer(params);
backBone.history.start();
extender.bind("list:selected",function(post){
listApp.navigate(post.category+'/'+post.filter);
});
my router code :
define(["backBone","singleton","listCollection","listView","listViews"],function(Backbone,singleton,listCollection,listView,listViews){
singleton.router = Backbone.Router.extend({
routes:{
"" :"appView",
"post" :"postView",
"projectName/:id" :"projectNameView",
"assignedTo/:id" :"assignedToView",
"sortBy/:id" :"sortByView"
},
initialize:function(params){
this.params = params;
this.collection = new listCollection;
console.log('i am called');
},
hashView:function(){
console.log('from hash view');
},
appView:function(){
var that = this;
// var defaultApp = new listCollection();
this.collection.fetch({
success:function(data){
new listViews({model:data,params:that.params})
}
})
},
projectNameView:function(thisView){ // not calling not sync
console.log('called',thisView); // on click not works
},
assignedToView:function(thisView){ // not calling not sync
console.log(thisView); // on click not works
},
sortByView:function(thisView){ // not calling not sync
console.log(thisView); // on click not works
}
});
return singleton.router;
})
thanks in advance.
navigate only updates the url, you also have to call the route function by setting the trigger option to true. If you'd like to update the URL without creating an entry in the browser's history, also set the replace option to true.
listApp.navigate(post.category+'/'+post.filter);
would become
listApp.navigate(post.category+'/'+post.filter, {trigger: true});

Resources