Show Modal on AngularJS $httpProvider: responseError - ajax

We need to hookup a Modal with a generic message on our failed Ajax calls in AngularJS.
i was able to intercept the error on the app.config part, but from there i am unable to import the $modal or the $scope to show the modal. What i got working so far is creating a function on my global scope and add the opening of the modal in my app.run:
var showGeneralException = function () { };
var app= angular.module('myApp', ['ui.bootstrap'])
.run(function ($rootScope, $modal) {
showGeneralException = function () {
var exceptionModel = $modal.open({
templateUrl: 'generalException',
controller: 'exceptionModals',
});
};
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
'responseError': function (rejection) {
showGeneralException();
}
};
});
});
When i perform it this way a modal opens but i get a not found exception in my modal and following errors in my debug console:
TypeError: Unable to get value of the property 'data': object is null or undefined
LOG: WARNING: Tried to load angular more than once.
LOG: WARNING: Tried to load angular more than once.
LOG: WARNING: Tried to load angular more than once.

Related

how set errors from laravel in vuejs

I am trying to retrieve errors from Laravel in Vue, but i get this error message in my console "Cannot set property 'errors' of undefined".
I have tried different approaches like direct assignment of errors and the $set() of vue to set error message to the error object of my data function, but it is still in vain.
This is my code
export default{
data(){
return{
form: {},
errors:{}
}
},
methods:{
async onSave() {
await Api().post('/stocks/store',this.form)
.then()
.catch(function (error) {
if(error.response && error.response.status == 422) {
let errors = error.response.data.errors;
// this.$set(this.$data.errors,'errors',errors)
console.log(errors);
this.errors = errors;
}
});
}
}
This is how the error message from my console
This is the error message from laravel
how do set this.errors with error message from laravel
If you look closely at the error, it says
Cannot set property 'errors' of undefined
So the problem is you are trying to set a property of an undefined object, in this case: this, your Vue component.
An easy and convenient way to solve this problem is to use arrow function instead of a regular function in your Promise.catch() callback. To put simply, a regular function expression has his own this context, where arrow function does not.
Here is a sample of code that should help you understand better:
new Promise().then()
.catch((error) => {
if(error.response && error.response.status == 422) {
this.errors = error.response.data.errors;
}
});
To learn more about arrow function and the binding of this

AngularJS Testing using Jasmine-Karma

I have a factory service inside a folder,,,i have mentioned the path in karma.conf.js file correctly and added the angular-mocks before that..But
if i try to load a factory/service which is not available in that folder then Unknown provider error is thrown
If i include the correct factory service then am not getting any error
But if i try to call a method in that factory/service,then the mocked service object is undefined and am getting cannot read a function from undefined error message..
I couldn't figure out why...can any1 help me in this issue..
Spec.js
describe('dfgh', function () {
var mockService,httpBackend;
beforeEach(function () {
module('app');
});
beforeEach(function () {
inject(function ($httpBackend, _familyService_) {
mockService = _familyService_;
httpBackend = $httpBackend;
});
});
it('Factory Service Testing', function () {
/// Code here
});
});
FamilySvc.js
(function() {
'use strict';
angular.module('app')
.factory('familyService', familyService);
familyService.$inject = ['$rootScope', '$http', '$q', 'service2', 'service3'];
function familyService() {
var a="Some String";
return a;
}
}());
Karma.conf.js
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'app/*.js', --> Holds FamilySvc.js
'tests/*.*' -- >holds Spec.js
],

Submodule becoming "undefined" in Backbone.Marionette app

I'm making a Marionette app for uploading files and I'm at the very beginning of it. To start things off, I will show you the files I'm working with:
upload_view.js
AppManager.module("PrimaryApp.Upload", function(Upload, AppManager, Backbone, Marionette, $, _){
Upload.UploadPage = Marionette.ItemView.extend({
template: "#upload-template"
});
});
upload_controller.js
AppManager.module("PrimaryApp.Upload", function(Upload, AppManager, Backbone, Marionette, $, _){
Upload.Controller = {
show: function(){
var uploadView = new Upload.UploadPage();
AppManager.regions.primary.show(uploadView);
},
};
});
app.js
var AppManager = new Marionette.Application();
AppManager.on("before:start", function() {
var RegionContainer = Marionette.LayoutView.extend({
el: "#app-container",
regions: {
primary: "#primary-region",
secondary: "#secondary-region",
header: "#header-region"
}
});
AppManager.regions = new RegionContainer();
});
AppManager.on("start", function(){
console.log(AppManager);
AppManager.PrimaryApp.Upload.Controller.show();
})
AppManager.start();
When running this application in a browser I get this error:
Uncaught TypeError: Cannot read property 'Upload' of undefined
For this line of code in app.js:
AppManager.PrimaryApp.Upload.Controller.show();
However, when I output AppManager to the console I get this:
Which shows that AppManager.PrimaryApp is indeed defined and contains all the submodules needed. Any ideas why my AppManager.PrimaryApp is undefined when called as a function, but then is defined when outputted to the console?
Figured out what was wrong!
AppManager.start();
Was in the wrong place and tried to run before AppManager.PrimaryApp was defined. However,
console.log(AppManager);
was somehow called after AppManager.PrimaryApp was defined resulting in a correct output. A simple move of my start() function fixed the order of things.

how to get the text of bootstrap alert message for testing with protractor

this is my spec
it('should save edited majorObject', function () {
var description = element(by.id('objectDescription'));
description.clear();
description.sendKeys('edited');
var add = element(by.id('saveObject'));
add.click().then(function () {
expect(element(by.css('.alert-success')).isDisplayed()).toBe(true);
expect(element(by.css('.alert-success')).toText()).toBe("Saved Successfully");
})
});
i used
expect(element(by.css('.alert-success')).toText()).toBe("Saved Successfully");
But it is showing undefined and is their any alternative way to do this?
You meant to use getText() instead of toText():
expect(element(by.css('.alert-success')).getText()).toBe("Saved Successfully");

angular - invoke() on exising element undefined

I've a div (id: dest) in which content is loaded via ajax using query.
I need to compile with angular the content of that div.
Here is the content loaded via ajax:
{{myvar}}
I tried to do:
var app = angular.module("myapp", []);
app.controller("myctrl", function($scope){
$scope.myvar = "hello world!";
});
$("#dest").attr("data-ng-app", "myapp");
$("#dest").attr("data-ng-controller", "myctrl");
console.log(angular.element($("#dest")).size()); //always returns '1'
angular.element($("#dest")).injector().invoke(function($compile) {
var scope = angular.element($("#dest")).scope();
$compile($("#dest"))(scope);
});
I'm sure that $("#dest") exists in dom when that code is executed but
angular.element($("#dest")).injector() is always undefined.
I also tried to wait 15 seconds:
setTimeout(function(){
angular.element($("#dest")).injector().invoke(function($compile) {
var scope = angular.element($("#dest")).scope();
$compile($("#dest"))(scope);
});
}, 15000);
But the problem remains.
PS.
I cannot interact directly with ajax request or response and the div (with id dest), exists at page loading.
Have you tried wrapping that code with $(document).ready() or angular's equivalent:
angular.element(document).ready(function () {
angular.element($("#dest")).injector().invoke(function($compile) {
var scope = angular.element($("#dest")).scope();
$compile($("#dest"))(scope);
});
});
Working jsfiddle.
Have you tried this :
angular.element($("#dest")).injector().invoke(['$compile', function($compile) {
var scope = angular.element($("#dest")).scope();
$compile($("#dest"))(scope);
}]);

Resources