I'm new in Lightning component development, and I'm trying to implement a lightning:datatable with several actions, like add a new line, delete a line, and create new line.
To create a line, I'm using a quick action, and I call it using quickActionAPI :
var actionAPI = component.find("quickActionAPI");
var args = { actionName :"Contrat_cadre__c.My_rule"};
var anAction = actionAPI.selectAction(args)
.then(function(result) {
})
.catch(function(e) {
if (e.errors) {
alert('The action is unavailable');
}
});
It's working as expected but well I need to manually refresh the page to see the new line in my datatable. But I don't know how to catch the subsmission of the quick action.
Try putting this in your "then" block: https://developer.salesforce.com/docs/component-library/bundle/force:refreshView/documentation
Thank you for your anwser, here is what I tried :
in controller.js :
var anAction = actionAPI.selectAction(args)
.then(function() {
console.log('enter in then');
helper.refreshPage();
})
in helper.js :
refreshPage: function (component)
{
console.log('helper method');
var action = component.get('c.**myApexController**');
action.setCallback(component,
function(response) {
var state = response.getState();
console.log(state);
if (state === 'SUCCESS'){
console.log('success');
$A.get('e.force:refreshView').fire();
} else {
//do something
}
}
);
$A.enqueueAction(action);
}
It seems that the then is fired when the action is invoked, so before the action submission. (the console.log display "enter in then" and "helper method" at this time, the other log does not display at all)
Related
Let's say, we were trying to delete an item from the list using the web api.We had created a child component named as remove-item using parameters - item and onRemove.On click of a item,we would like to trigger the callback function to the parent component.As per the code,onRemove is not getting called after deleting the item.Can someone help us figure out the error and provide us the right solution with an illustration.
remove.component.js
-------------------
this.RemoveItem = function (index) {
var promise = productList.removeItem(parseInt(this.id));
promise.then(function (response) {
console.log("An item has been deleted");
this.items=response.data;
}, function (error) {
console.log("An error has occurred while deleting the item:", this.id);
});
this.onRemove({
$index: this.items
});
}
I would avoid using 'this'. Not sure why you passed index param in RemoveItem fn , can't see you use it anywhere in this scope. Anyway if productList.removeItem returns Promise than we can call onRemove. I would def need more information - html code and your remove fn code but try this anyway.
let vm = this;
vm.RemoveItems = RemoveItem;
vm.onRemove = onRemove;
RemoveItem(index) {
productList.removeItem(parseInt(this.id))
.then(function (response) {
console.log("An item has been deleted");
vm.onRemove({$index: response.data});
}, function (error) {
console.log("An error has occurred while deleting the item:", this.id);
});
}
onRemove(obj) {
console.log(obj);
//make your remove here
}
I am trying to update record using Angular js method my html is like,
<button type="button" ng-click="delete()">'Update'</button>
delete method calling on angular js is,
$scope.delete = function () {
tasksService.getData($scope.ids).then(function (d) {
var result = JSON.parse(d.data.data);
});
if (confirm("Sure to update status +'result.name'+ For building?")) {
}
}
This code gets call on click but moved to last line confirmation after clicking on OK button later it call getData method i get result in var result
Actually i need to show some data from result in Confirmation Text
Hopes for your suggestions thanks
Try to show the confirm message in the success of the getData(). This will make the control wait for the response of getData().
$scope.delete = function () {
tasksService.getData($scope.ids).then(function (d) {
var result = JSON.parse(d.data.data);
if (confirm("Sure to update status " + result.name + "For building?")) {
}
});
}
This might help
Pass some value when function is called
HTML
<button type="button" ng-click="delete(value)">'Update'</button>
JS
$scope.delete = function (value) { // passed value
tasksService.getData($scope.ids).then(function (d) {
var result = JSON.parse(d.data.data);
if (confirm("Sure to update status " + value.name + "For building?")) {
}
});
}
I have a project that uses angular's $http service to load data from a remote location. I want to use rxjs Observables so the call in my service looks like this:
userInfo() : Rx.Observable<IUserInfo> {
var url : string = someUrl + this._accessToken;
return Rx.Observable.fromPromise<IUserInfo>( this.$http.get<IUserInfo>( url ) );
}
and this is subscribed to by my controller like this:
getUserInfo() : void {
this._googleService.userInfo().subscribe(
( result ) => { this.handleUserInfo( result ) },
( fault : string ) => this.handleError( fault )
)
}
private handleUserInfo( result : IHttpPromiseCallbackArg<IUserInfo> ) : void {
console.log( "User info received at " + new Date() );
this._name = result.data.given_name + " " + result.data.family_name;
this._email = result.data.email;
this._profilePicUrl = result.data.picture;
}
the problem is that despite the name, email and profile pic being updated these changes are not visible. As soon as anything else triggers an angular $apply the changes appear but because of the Observable these changes in the controller happen after the angular digest loop that is triggered by the $http call.
This does work correctly if my service just returns a promise to the controller.
How do I update my view in this case? I do not want to manually have to wire up each observable to trigger a digest cycle. I want all Observables to trigger a digest cycle when they receive a new value or error.
We can use the ScopeScheduler from rx.angular.js for this. We only have to create a new one where we create our angular module and pass the $rootScope to it:
const module : ng.IModule = angular.module( 'moduleName', [] );
module.run( ["$rootScope", ( $rootScope ) => {
new Rx.ScopeScheduler( $rootScope );
}]);
That's all you have to do. Now all Rx.Observables trigger an $apply when they get a new value.
For some reason the ScopeScheduler was deleted when the rx.angular.js library was upgraded to rxjs version 4. We have to use rx.angular.js version 0.0.14 to use the ScopeScheduler.
I do not know what the suggested solution to this is in version 4.
A project using this fix can be viewed here:
https://github.com/Roaders/Typescript-OAuth-SPA/tree/observable_apply_issues
I couldn't get the Rx.ScopeScheduler method to work, so I just overwrote the rx observable subscribe method itself instead, and wrapped the callbacks in $rootScope.$apply :)
module.run(['$rootScope', 'rx', function ($rootScope, rx) {
rx.Observable.prototype.subscribe = function (n, e, c) {
if(typeof n === 'object') {
return this._subscribe(n);
}
var onNext = function(){};
if(n) {
onNext = function(value) {
if($rootScope.$$phase) {
n(value);
}
else {
$rootScope.$apply(function(){ n(value); });
}
};
}
var onError = function(err) { throw err; };
if(e) {
onError = function(error) {
if($rootScope.$$phase) {
e(error);
}
else {
$rootScope.$apply(function(){ e(error); });
}
};
}
var onCompleted = function(){};
if(c) {
onCompleted = function() {
if($rootScope.$$phase) {
c();
}
else {
$rootScope.$apply(function(){ c(); });
}
};
}
return this._subscribe(
new rx.AnonymousObserver(onNext, onError, onCompleted)
);
};
}]);
Ok i have this button :
and i have this function for confirm ticket:
$scope.ConfirmTicketPayOut = function (ticketPin, username)
{
$scope.ticketPin = ticketPin;
localStorage.setItem("ticketPin", ticketPin);
accountDataProviderService.confirmTicketPayOut(ticketPin, username)
.then(function (response) {
$scope.confirmTicketPayOut = response;
if ($scope.confirmTicketPayOut.Result == true)
{
var w = $window.open('/account/ticketprint');
angular.element(w).bind('load', function () {
w.print();
});
}
});
}
I have problem because when user click on button i need to open new window with data and to call print option. In this case i get print option and new window is open but the page is blank so my conclusion is that page is loaded after print option is appeared. I need to load page and show print option at same time, but without $timeout. Is that possible?
Try using angular event viewContentLoaded. call your method after this event is fired.
Example
$scope.$on('$viewContentLoaded', function() {
// Your method call
}
I'm using Firebase for my Angular.js application.
I'm looking for the equivalent of SQL's WHERE statement for Firebase.
I have an array of TV series stored in Firebase, and I want to fetch only these that has the name that the user entered (in the example searchQuery).
Does Firebase support it? Does it have something like this?
var seriesRef = new Firebase('http://{app}.firebaseio.com/series');
var seriesObject = $firebaseObject(seriesRef.query({ name: searchQuery }));
I have some suggestions that may help here:
Check out the Firebase Query documentation. Specifically,
.orderByChild()
.equalTo()
You can use queries in conjunction with .$ref() to get the desired record.
Example
Check out this working CodePen demo.
I replicated your data in one of my public Firebase instances.
The query that you're looking for is seriesCollectionRef.orderByChild('name').equalTo(seriesName)
If you enter 'Avatar: The Last Airbender' in the input and click "Find", you'll get the matching series object.
In my example, I extended the $firebaseArray service to include a method for finding a specific series by name.
See the documentation for extending AngularFire services.
You can accomplish the same thing without extending the service, see last code snippet.
Factories
app.factory('SeriesFactory', function(SeriesArrayFactory, fbUrl) {
return function() {
const ref = new Firebase(`${fbUrl}/series`);
return new SeriesArrayFactory(ref);
}
});
app.factory('SeriesArrayFactory', function($firebaseArray, $q) {
return $firebaseArray.$extend({
findSeries: function(seriesName) {
const deferred = $q.defer();
// query by 'name'
this.$ref()
.orderByChild('name')
.equalTo(seriesName)
.once('value', function(dataSnapshot) {
if (dataSnapshot.exists()) {
const value = dataSnapshot.val();
deferred.resolve(value);
} else {
deferred.reject('Not found');
}
})
return deferred.promise;
}
});
});
Controller
app.controller('HomeController',function($scope, SeriesFactory, fbUrl) {
$scope.seriesName = '';
$scope.findSeries = function() {
const seriesCollection = new SeriesFactory();
seriesCollection
.findSeries($scope.seriesName)
.then(function(data) {
$scope.series = data;
})
.catch(function(error) {
console.error(error);
});
};
});
Without Extended Service
Here is what a controller function would look like if you weren't using the factories:
$scope.findSeriesWithoutFactory = function() {
const seriesRef = new Firebase(`${fbUrl}/series`);
const seriesCollection = $firebaseArray(seriesRef);
seriesCollection.$ref()
.orderByChild('name')
.equalTo($scope.seriesName)
.once('value', function(dataSnapshot) {
if (dataSnapshot.exists()){
$scope.series = dataSnapshot.val();
} else {
console.error('Not found.');
}
});
};
Rules
Note: It's important to note that you should add ".indexOn": "name" to your Firebase rules so that the query runs efficiently. See the Indexing Your Data portion of the Firebase Security & Rules Guide for more information. Below is an example:
"yourfirebaseapp": {
".read": "...",
".write": "...",
"series": {
".indexOn": "name"
}
}