Angular http testing - testing

I have a fairly simple controller that gets a simple json list of objects ...
function ProductGroupsCtrl($scope, $http, $routeParams, sharedService, popupService) {
$scope.list = null;
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
$scope.selectItem = function (item) {
$scope.selectedItem = item;
$scope.selectedItemJsonString = JSON.stringify(item);
//alert(JSON.stringify(item));
};
$scope.closePopup = function () {
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
};
// sharedService.prepForBroadcast($routeParams.anotherVar);
$http({
method: 'GET',
url: '/ProductGroup'
}).success(function (data) {
$scope.list = data;
}).
error(function (data) {
$scope.message = 'There was an error with the data request.';
});
}
I then try to mock the request in the test class:
var scope, ctrl, $httpBackend, sharedServiceMock = {}, popupServiceMock = {};
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httsypBackend.expectGET('/ProductGroup').
respond([{
ProductGroupID: 5,
MenuTitle: "Promotional Products",
AlternativeText: "Coming soon - a collection of environmentally friendly Promotional Products",
OrdinalPosition: 5,
Active: false
}]);
scope = $rootScope.$new();
ctrl = $controller(ProductGroupsCtrl, {
$scope: scope,
$http: $httpBackend,
sharedService: sharedServiceMock,
popupService: popupServiceMock
});}));
However I receive an error in the testacular window object undefined. What have I done wrong here?

Found the answer. If I remove the error callback function from the $http.get method then it works, i.e. remove the following ...
error(function (data) {
$scope.message = 'There was an error with the data request.';
}
I have to say Angular sure is a steep learning curve for someone who is not a day to day JavaScript programmer (although I seem to be doing more and more). Thanks for the help anyway KatieK :-)

Related

How can I refresh datatable in Wire using refreshApex

#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({error,data}){
this.dataToRefresh = data;
if (data) {
this.contacts = this.dataToRefresh.recordList;
this.ContactsRecords = this.dataToRefresh.cList;
this.contactsSize = " Case Contacts (" + this.contacts.length + ")";
}else{
//
}
};
relateContacts() {
this.showSpinner = true;
this.showtable=false;
relateContacts({contacts: this.selected, recordId: this.recordId})
.then(data => {
this.showSpinner=false;
this.showtable=true;
this.showSuccessMessage();
refreshApex(this.dataToRefresh);
//location.reload();
this.isShowModal = false;
})
.catch(error => {
console.log(error);
this.showSpinner=false;
const evt = new ShowToastEvent({
title: 'Application Error',
message: error.body.message,
variant: 'error',
mode: 'sticky'
});
this.dispatchEvent(evt);
this.showSpinner = false;
});
}
For this code, I tried refreshApex with all possible ways. but I'm not sure the miss here. I've Checked all the blogs but everywhere, the solution is mentioned.
Tried refreshApex like below :
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({data}){
this.dataToRefresh = data;
But this also does not work
Ah that is a fun one ! Your issue is using destructuring in wiredContacts as the parameter.
(The {data} or {data,error} normally works as a parameter to the function being called back, except if you have to do refresh) Try this instead.
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts(value){
this.dataToRefresh = value;
const {data, error} = value;
//Rest of you code now with data and error
}
Then in your other method you can do:
method(){
refreshApex(this.dataToRefresh);
}
Salesforce does show doing this in their example code, but it’s easy to miss and experience the fun you have been having with this.
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex_result_caching
See the last example on their page.

vline add remote stream for callee fail

I am trying to use your api in a custom app with imported users.
Everything works fine (auth_token, login, call initiation) , but when the callee should get a response and add the remotestream nothing happens. no errors get shown in the console.
I would appreciate if someone takes a look at the code and tells me what i m missing.
I tried the vline demo at https://freeofcinema.vline.com and it worked with the same browsers and conditions between the two computers. In my app it is a http , but i tried it also with https, and the same problem came up. This is some simplified code i used to test the api.
var Streams = [];
var Vsession = null;
var Vline = (function(){
var Client;
var authToken;
var service_id = 'freeofcinema';
var profile = null;
var Person;
var Calls = [];
var onMessage = function(event){
//alert('message');
var msg = event.message, sender = msg.getSender();
console.log(sender.getDisplayName() +'sais: '+ msg.getBody());
console.log(event);
}
var onMediaSession = function(event){
console.log(event);
var mediaSession = event.target;
InitSession(mediaSession);
}
function Call(mediaSession) {
mediaSession.
on('change', alert_info);
}
function alert_info(b){
console.log(b);
}
function InitSession(mediaSession){
mediaSession.on('mediaSession:addRemoteStream', function(event) {
alert('addRemoteStream');
});
mediaSession.on('mediaSession:addLocalStream', function(event) {
alert('addLocalStream');
});
mediaSession.on('mediaSession:removeLocalStream mediaSession:removeRemoteStream', function(event) {
console.log('removedStream');
});
Calls.push(new Call(mediaSession));
}
return {
init : function(){
if(profile){
return;
}
profile = {
"displayName" : //some getusrname function...
};
$.post('vtoken.php',{//get auth token
id : Comm.Voip_user().id
},function(data){
authToken = data;
Client = vline.Client.create({
"serviceId": service_id,
"ui" : true
});
Client.on('recv:im', onMessage , this);
Client.on('add:mediaSession', onMediaSession, this);
Client.on('login', function(e) {
Vsession = e.target;
//alert('loged in');
});
Client.login(service_id, profile, authToken);
});
},
getPerson : function(id){//id of user to call
if(Vsession){
Vsession.getPerson(id).
done(function(person){
Person = person;
Vsession.startMedia(id);
});
}
}
}
}());
Thank you for your response.
I tried with one user from the app, and another from the https://freeofcinema.vline.com, and the same problem occured. Also the call (in pending state) gets terminated after a short while..
When passing ui:true when creating the client, you do not have to handle the media sessions yourself. Just comment the line Client.on('add:mediaSession', onMediaSession, this); and it should just work.

knockout.js api search form

The goal of my code is to search on the API search string:
So if you fill out the form you get the hits bij name.
I used the following Knockout.js script:
var viewModel=
{
query : ko.observable("wis"),
};
function EmployeesViewModel(query)
{
var self = this;
self.employees = ko.observableArray();
self.query = ko.observable(query);
self.baseUri = BASE + "/api/v1/search?resource=employees&field=achternaam&q=";
self.apiurl = ko.computed(function() {
return self.baseUri + self.query();
}, self);
//$.getJSON(baseUri, self.employees);
//$.getJSON(self.baseUri, self.employees);
$.getJSON(self.apiurl(), self.employees);
};
$(document).ready(function () {
ko.applyBindings(new EmployeesViewModel(viewModel.query()));
});
The html binding is:
<input type="text" class="search-query" placeholder="Search" id="global-search" data-bind="value: query, valueUpdate: 'keyup'"/>
But if i fill the text box i onley get the default "wis" employees? What am I doing wrong?
Not entirely sure what is wrong here, but have you debugged it and seen what the value of query is in apiurl?
One potential issue is that you are passing employees to getJSON as the observable, not the underlying array, so you could try:
$.getJSON(self.apiurl(), self.employees());
After some digging I found a solution.
var employeesModel = function(){
var self = this;
self.u = base +'/api/v1/search';
self.resource = 'employees';
self.field = 'achternaam';
self.employees = ko.observableArray([]);
self.q = ko.observable();
//Load Json when model is setup
self.dummyCompute = ko.computed(function() {
$.getJSON(self.u,{'resource': self.resource, 'field': self.field, 'q':self.q }, function(data) {
self.employees(data);
});
}, self);
};
ko.applyBindings(new employeesModel());

Win 8 Apps : saving and retrieving data in roamingfolder

I'm trying to store few user data into a roamingFolder method/property of Windows Storage in an app using JavaScript. I'm following a sample code from the Dev Center, but no success. My code snippet is as follows : (OR SkyDrive link for the full project : https://skydrive.live.com/redir?resid=F4CAEFCD620982EB!105&authkey=!AE-ziM-BLJuYj7A )
filesReadCounter: function() {
roamingFolder.getFileAsync(filename)
.then(function (filename) {
return Windows.Storage.FileIO.readTextAsync(filename);
}).done(function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// getFileAsync or readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
filesDisplayOutput: function () {
this.filesReadCounter();
}
I'm calling filesDisplayOutput function inside ready method of navigator template's item.js file, to retrieve last session's data. But it always shows blank. I want to save upto 5 data a user may need to save.
I had some trouble running your code as is, but that's tangential to the question. Bottom line, you're not actually reading the file. Note this code, there's no then or done to execute when the promise is fulfilled.
return Windows.Storage.FileIO.readTextAsync(filename);
I hacked this in your example solution and it's working... typical caveats of this is not production code :)
filesReadCounter: function () {
roamingFolder.getFileAsync(filename).then(
function (filename) {
Windows.Storage.FileIO.readTextAsync(filename).done(
function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
function () {
// getFileAsync failed
})
},

Deferring a Dojo Deferred

I'm having a bit of a problem getting a deferred returned from a method in a widget. The method is itself returns a Deferred as it's an xhrPost. The code is as such (using dojo 1.8)
Calling Code:
quorum = registry.byId("quorumPanel");
var deferredResponse = quorum.updateSelectionCount();
deferredResponse.then(function(data){
console.log("Success: ", data);
}, function(err){
console.log("Error: ", err);
});
and the code in the widget:
updateSelectionCount: function() {
var self = this;
var deferredResponse = xhr.post({
url: "ajxclwrp.php",
content: [arguments here],
handleAs: "json"});
deferredResponse.then(function(response) {
var anotherDeferred = new Deferred();
var _boolA = true;
var _boolB = true;
dojo.forEach(response.result, function(relationshipInfo){
[do a bunch of stuff here too set _boolA and/or _boolB]
});
self._sethasRequiredAttr(_hasRequired);
self._setHasRequestedAttr(_hasRequested);
self.quorumInfo.innerHTML = quorumHtml;
// Below is not working
anotherDeferred.resolve('foo');
return anotherDeferred;
});
}
Do I need to set up another promise and use promise/all. Im confused/frustrated at this point.
TIA.
the .then() method returns another deferred. You just need to put a return statement in.
updateSelectionCount: function() {
var self = this;
var deferredResponse = xhr.post({
url: "ajxclwrp.php",
content: [arguments here],
handleAs: "json"});
return deferredResponse.then(function(response) {
var _boolA = true;
var _boolB = true;
dojo.forEach(response.result, function(relationshipInfo){
[do a bunch of stuff here too set _boolA and/or _boolB]
});
self._sethasRequiredAttr(_hasRequired);
self._setHasRequestedAttr(_hasRequested);
self.quorumInfo.innerHTML = quorumHtml;
return "foo";
});
}