index of array changed inside ionic popup.then - javascript

Here is my code after simplified:
for (var i = 0; i < list.length; i++) { //list.length == 2.
var confirmPopup = $ionicPopup.confirm({
title: 'title',
template: 'confirming message'
});
console.log(i); // i == 0, which is correct.
confirmPopup.then(function (res) {
if (res) {
console.log(i); //i == 2, which is wrong, should be 0.
list[i].property = true; //property of undefined error occur here. Because i is 2, list.length is 2, so there's no list[2] actually.
}
else {
list[i].property = false; //same here.
}
});
}
So my issue is, I want to change list[i].property based on user's confirmation. But I don't know why the index changed from 0 to 2, I feel there's something to do with this comfirmPopup.then. Wondering how to fix this?

I don't know if I've understood you correctly but take a look at the snippet below.
The issues you had were the following:
You said that you have a list of numbers. Is that an array of numbers, or an array of objects? If it was just an array of numbers, that would explain why you're getting undefined. See the snippet for how I set up the array.
The main problem you're having is that you're trying to use i after confirmPopup.then(function (res) {, but by then, i will already have been destroyed. The res in confirmPopup.then(function (res) { is basically the result of your popup selection. This means that if you select "OK", then it will try to insert the value of i, by which time the loop will have already been terminated.
Maybe this will help you.
angular.module('ionicApp', ['ionic'])
.controller('Ctrl1', function($scope, $ionicPopup) {
var i = 0;
var list = [];
list = [{number: 123, property: false}, {number: 456, property: false}, {number: 678, property: true}];
var runPopUp = function() {
var confirmPopup = $ionicPopup.confirm({
title: 'title',
template: 'confirming message'
});
confirmPopup.then(function (res) {
if (res) {
list[i].property = true;
alert(list[i].number + " = " + list[i].property);
i++;
}
else {
list[i].property = false;
alert(list[i].number + " = " + list[i].property);
i++;
}
})
}
$scope.toggle = function() {
for (i; i < list.length; i++) {
runPopUp();
}
i = 0;
}
})
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic Template</title>
<link href="http://code.ionicframework.com/1.0.0-beta.2/css/ionic.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.0.0-beta.2/js/ionic.bundle.js">
</script>
</head>
<body ng-controller="Ctrl1">
</ion-content>
<div>
123 is false; 456 is false; 678 is true;
<button class="button button-small button-positive" ng-click="toggle()">Set Properties</button>
</div>
</ion-content>
</body>
</html>

Here's the nice solution:
Use list.forEach instead of for loop:
list.forEach(function (item) {
var confirmPopup = $ionicPopup.confirm({
title: 'title',
template: 'confirming message'
});
confirmPopup.then(function (res) {
if (res) {
item.property = true;
}
else {
item.property = false;
}
});
});

Related

Dynamically creating JavaScript handler

I'm trying to make the creation of these event handlers in this CodePen dynamic.
There are two viewers, and each has a handler. What if I want 4 viewers? I have to repeat the code over and over.
So instead of doing this:
var viewer1Leading = false;
var viewer2Leading = false;
var viewer1Handler = function() {
if (viewer2Leading) {
return;
}
viewer1Leading = true;
viewer2.viewport.zoomTo(viewer1.viewport.getZoom());
viewer2.viewport.panTo(viewer1.viewport.getCenter());
viewer1Leading = false;
};
var viewer2Handler = function() {
if (viewer1Leading) {
return;
}
viewer2Leading = true;
viewer1.viewport.zoomTo(viewer2.viewport.getZoom());
viewer1.viewport.panTo(viewer2.viewport.getCenter());
viewer2Leading = false;
};
viewer1.addHandler('zoom', viewer1Handler);
viewer2.addHandler('zoom', viewer2Handler);
viewer1.addHandler('pan', viewer1Handler);
viewer2.addHandler('pan', viewer2Handler);
I want to be able to sort of do that:
// Our array of viewers
let objArray = [createViewerObj(viewer1), createViewerObj(viewer2)];
// We need a viewer handler for each viewer
let viewerHandler = function (activeViewer, objArray) {
let theOthers = [];
for (let i = 0; i < objArray.length; i++) {
if (activeViewer.id !== objArray[i].id) {
theOthers.push(objArray[i]);
}
}
// OK, now I have an array of everything but the "active" viewer.
for (let i = 0; i < theOthers.length; i++) {
// If any other viewer is leading, return.
if (theOthers[i].isLeading) {
return;
}
}
activeViewer.isLeading = true; // Turn on.
objArray.forEach(function (obj) {
// Set viewport for all viewers
obj.viewer.viewport.zoomTo(activeViewer.viewport.getZoom());
obj.viewer.viewport.panTo(activeViewer.viewport.getCenter());
});
activeViewer.isLeading = false; // Turn off.
};
// Add handlers
objArray.forEach(function (obj) {
// When Viewer i is zooming we want Viewer i to lead
obj.viewer.addHandler('zoom', viewerHandler(obj.viewer, objArray));
// When Viewer i is panning we want Viewer i to lead
obj.viewer.addHandler('pan', viewerHandler(obj.viewer, objArray));
});
// Create obj with props
function createViewerObj(viewer) {
return {
id: viewer.id,
isLeading: false,
viewer: viewer
}
}
But it's not working - the viewers are no longer synchronized.
Also I wanted to make the code less clunky, but now it's more clunky.
Any ideas?
Modified CodePen here.
var globalConfig = {
Image: {
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
Url: "//openseadragon.github.io/example-images/duomo/duomo_files/",
Format: "jpg",
Overlap: "2",
TileSize: "256",
Size: {
Width: "13920",
Height: "10200"
}
}
};
function createSyncedViews(imageSrc, ids) {
var syncedViews = []
var activeViewer = null; //magic init
ids.forEach(function (id) {
var currentViewer = OpenSeadragon({
id: id,
prefixUrl: imageSrc,
tileSources: globalConfig
})
currentViewer.addHandler('pan', handler);
currentViewer.addHandler('zoom', handler);
function handler() {
console.log(id, activeViewer);
//this magic is required to skip few initial events triggering while image is loading or whatever
//without it, this funky DraagonView will end up in stackoverlow
if (activeViewer == null)activeViewer = id;
if (activeViewer != id)return;
//end magic
syncedViews.forEach(function (view) {
if (view.id == id) {
return
}
view.viewport.zoomTo(currentViewer.viewport.getZoom());
view.viewport.panTo(currentViewer.viewport.getCenter());
})
//magic support
activeViewer = null;
}
syncedViews.push(currentViewer)
})
}
createSyncedViews("//openseadragon.github.io/openseadragon/images/", ['viewer1', 'viewer2','viewer3'])
try this
this is my way
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Synchronized Viewers</title>
<style>
.seadragon-viewer {
display: inline-block;
width: 45%;
height: 600px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="//openseadragon.github.io/openseadragon/openseadragon.min.js"></script>
<script>
// Define our image
var duomo = {
Image: {
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
Url: "//openseadragon.github.io/example-images/duomo/duomo_files/",
Format: "jpg",
Overlap: "2",
TileSize: "256",
Size: {
Width: "13920",
Height: "10200"
}
}
};
// Create osd viewer
function createViewer(id, tileSources) {
return OpenSeadragon({
id: id,
prefixUrl: "//openseadragon.github.io/openseadragon/images/",
tileSources: tileSources
});
}
// Create obj with props
function createViewerObj(viewer) {
return {
id: viewer.id,
isLeading: false,
viewer: viewer
}
}
// Now create the viewers
$(function(){
function dynamic_createView(arrViews){
var htmlContent="";
for (var i = 0; i < arrViews.length; i++) {
htmlContent+='<div id="'+arrViews[i]+'" class="seadragon-viewer"></div>';
}
$("#mainView")[0].innerHTML=htmlContent;
for (var i = 0; i < arrViews.length; i++) {
window[arrViews[i]]= createViewer(arrViews[i],duomo);
}
var objArray= [];
for (var i = 0; i < arrViews.length; i++) {
objArray[i]=createViewerObj(window[arrViews[i]]);
}
// We need a viewer handler for each viewer
var viewerHandler = function (activeViewer, objArray) {
var theOthers = [];
for (var i = 0; i < objArray.length; i++) {
if (activeViewer.id !== objArray[i].id) {
theOthers.push(objArray[i]);
}
}
// OK, now I have an array of everything but the "active" viewer.
for (var i = 0; i < theOthers.length; i++) {
// If any other viewer is leading, return.
if (theOthers[i].isLeading) {
return;
}
}
activeViewer.isLeading = true; // Turn on.
objArray.forEach(function (obj) {
// Set viewport for all viewers
obj.viewer.viewport.zoomTo(activeViewer.viewport.getZoom());
obj.viewer.viewport.panTo(activeViewer.viewport.getCenter());
});
activeViewer.isLeading = false; // Turn off.
};
// Add handlers
objArray.forEach(function (obj) {
// When Viewer i is zooming we want Viewer i to lead
obj.viewer.addHandler('zoom', viewerHandler(obj.viewer, objArray));
// When Viewer i is panning we want Viewer i to lead
obj.viewer.addHandler('pan', viewerHandler(obj.viewer, objArray));
});
}
dynamic_createView(["viewer1","viewer2","viewer3"]);
});
</script>
</head>
<body>
<div id="mainView"></div>
</body>
</html>

JQuery autocomplete error : Cannot read property 'label' of undefined

With reference to AutoComplete in Bot Framework , I had implemented GET method of search URL.
Below is my code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link href="https://cdn.botframework.com/botframework-
webchat/latest/botchat.css" rel="stylesheet" />
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
<link rel="stylesheet"
href="https://jqueryui.com/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdn.botframework.com/botframework-
webchat/latest/botchat.js"></script>
<style>
.wc-chatview-panel {
width: 350px;
height: 500px;
position: relative;
}
</style>
</head>
<body>
<div id="mybot"></div>
</body>
</html>
<script src="https://cdn.botframework.com/botframework-
webchat/latest/CognitiveServices.js"></script>
<script type="text/javascript">
var searchServiceName = "abc";
var searchServiceApiKey = "xyzabc";
var indexName = "index1";
var apiVersion = "2017-11-11";
var corsanywhere = "https://cors-anywhere.herokuapp.com/";
var suggestUri = "https://" + searchServiceName + ".search.windows.net/indexes/" + indexName + "/docs/suggest?api-version=" + apiVersion + "&search=how";
var autocompleteUri = "https://" + searchServiceName + ".search.windows.net/indexes/" + indexName + "/docs/autocomplete?api-version=" + apiVersion;
var searchUri = corsanywhere + "https://" + searchServiceName + ".search.windows.net/indexes/" + indexName + "/docs?api-version=" + apiVersion;
BotChat.App({
directLine: {
secret: "DIRECTLINEKEY"
},
user: {
id: 'You'
},
bot: {
id: '{BOTID}'
},
resize: 'detect'
}, document.getElementById("mybot"));
</script>
<script type="text/javascript">
$(function () {
$("input.wc-shellinput").autocomplete({
source: function (request, response) {
$.ajax({
type: "GET",
url: searchUri,
dataType: "json",
headers: {
"api-key": searchServiceApiKey,
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "SAMPLEURL",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE"
},
data: JSON.stringify({
top: 5,
fuzzy: false,
// suggesterName: "", //Suggester Name according to azure search index.
search: request.term
}),
success: function (data) {
if (data.value && data.value.length > 0) {
//RESPONSE FORMATTED as per requirements to hold questions based on input value(Below code is only for my reference i added)
var result = "";
var inputValue = request.term;
for (i = 0; i < data.value.length; i++) {
var allquestions = data.value[i].questions;
if (allquestions.length > 0) {
for (j = 0; j < allquestions.length; j++)
if (allquestions[j].toLowerCase().indexOf(inputValue.toLowerCase()) != -1) {
result = result + "," + allquestions[j];
}
}
}
if (result != null) {
alert(result);
response(data.value.map(x => x["#search.text"])); ---Caught Error at this STEP
}
else { alert("no data"); }
}
else {
alert("No response for specific search term");
}
}
});
},
minLength: 3,
position: {
my: "left top",
at: "left bottom",
collision: "fit flip"
},
select: function (Event, ui) {
$(document).ready(function () {
var input = document.getElementsByClassName("wc-shellinput")[0];
var lastValue = input.value;
input.value = ui.item.value;
var event = new CustomEvent('input', {
bubbles: true
});
// hack React15
event.simulated = true;
// hack React16
var tracker = input._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
input.dispatchEvent(event);
})
$('wc-textbox').val("");
Event.preventDefault();
$(".wc-send:first").click();
}
});
});
</script>
My Sample API Output:
{ "#odata.context": "URL", "value": [{ "questions": [ "where are you", "where have you been", ] }, { "questions": [ "How are you?" ] } ] }
I am getting API response successfully (data.value) but got exception at
response(data.value.map(x => x["#search.text"]));
Error Message:Uncaught TypeError: Cannot read property 'label' of undefined
I had tried replacing #search.text with "value" and "#data.context" but still am getting error. I want to display all questions data based on user input
I am finally able to fix my issue with below solution.
Note: JQuery Autocomplete "response" method takes array as data type.
Solution:
1) when we are passing entire API array results to "response" method, results must have "label" keyword with proper data.
sample code while passing entire API results:
response(data.value.map(x => x["#search.text"]));
2) when we don't have "label" keyword in API response, we have to format response as per requirements and create a new array of data that we want to display as auto suggest and pass to "response" method.
Below is code for same:
var autoSuggestDataToDisplay= [];
var inputValue = request.term;
for (i = 0; i < data.value.length; i++) {
var allquestions = data.value[i].questions;
if (allquestions.length > 0) {
for (j = 0; j < allquestions.length; j++)
if (allquestions[j].toLowerCase().indexOf(inputValue.toLowerCase()) != -1) {
result = result + "," + allquestions[j];
if (autoSuggestDataToDisplay.indexOf(allquestions[j].toLowerCase()) === -1) {
autoSuggestDataToDisplay.push(allquestions[j].toLowerCase());
}
}
}
}
if (result != null) { response(autoSuggestDataToDisplay); }
else { alert("no data"); }
As i dont have "label" in API response, I followed #2 approach and solved it.

Update JS model through MVC not change

i have variables as a model, i were able to change it temporary but when try to update other values it's fetched in the controller but when try to re render it again it show the new value and retrieve the old value quickly,
the issue in updateCat func i think, also i want to pass form is object not each value alone as updated-name and updated-img.
Thanks in advance.
/* ======= Model ======= */
var model = {
currentCat: null,
cats: [
{
clickCount: 0,
name: 'Tabby',
imgSrc: 'img/434164568_fea0ad4013_z.jpg',
imgAttribution: 'https://www.flickr.com/photos/bigtallguy/434164568',
isAdmin: 0
},
{
clickCount: 0,
name: 'Tiger',
imgSrc: 'img/4154543904_6e2428c421_z.jpg',
imgAttribution: 'https://www.flickr.com/photos/xshamx/4154543904',
isAdmin: 0
},
{
clickCount: 0,
name: 'Scaredy',
imgSrc: 'img/22252709_010df3379e_z.jpg',
imgAttribution: 'https://www.flickr.com/photos/kpjas/22252709',
isAdmin: 0
},
{
clickCount: 0,
name: 'Shadow',
imgSrc: 'img/1413379559_412a540d29_z.jpg',
imgAttribution: 'https://www.flickr.com/photos/malfet/1413379559',
isAdmin: 0
},
{
clickCount: 0,
name: 'Sleepy',
imgSrc: 'img/9648464288_2516b35537_z.jpg',
imgAttribution: 'https://www.flickr.com/photos/onesharp/9648464288',
isAdmin: 0
}
]
};
/* ======= Octopus ======= */
var octopus = {
init: function () {
// set our current cat to the first one in the list
model.currentCat = model.cats[0];
// tell our views to initialize
catViewList.init();
catView.init();
},
getCurrentCat: function () {
return model.currentCat;
},
getCats: function () {
return model.cats;
},
// set the currently-selected cat to the object passed in
setCurrentCat: function (cat) {
model.currentCat = cat;
},
// increments the counter for the currently-selected cat
incrementCounter: function () {
model.currentCat.clickCount++;
catView.render();
},
// Admin mode, to edit exist cat (name, url)
showAdminForm: function () {
model.currentCat.isAdmin = 1;
catView.render();
},
updateCat: function (name, img) {
console.log(name + " ----- " + img + " before currentCat " + model.currentCat.name);
model.currentCat.name = name;
model.currentCat.imgSrc = img;
catView.render();
}
};
/* ======= View ======= */
var catView = {
init: function () {
// POINTERS
this.catElem = document.getElementById('cat-div');
this.catNameElem = document.getElementById('cat-name');
this.catCounter = document.getElementById('cat-counter');
this.catImage = document.getElementById('cat-image');
this.isAdmin = document.getElementById('show-admin');
this.adminPanel = document.getElementById('admin-panel');
this.newName = document.getElementById('updated-name');
this.newImg = document.getElementById('updated-name');
this.isAdmin.addEventListener('click', function () {
octopus.showAdminForm();
});
this.catImage.addEventListener('click', function () {
// Get count from octopus
octopus.incrementCounter();
});
this.render();
},
render: function () {
// Empty the form
// this.isAdmin.innerHTML = '';
// update the DOM elements with values from the current cat
var currentCat = octopus.getCurrentCat();
this.catCounter.textContent = currentCat.clickCount;
this.catNameElem.textContent = currentCat.name;
this.catImage.src = currentCat.imgSrc;
this.isAdmin = currentCat.isAdmin;
this.newName.textContent = currentCat.name;
this.newImg.src = currentCat.imgSrc;
this.adminPanel.addEventListener('submit', function() {
var updatedName = document.getElementById("updated-name").value;
var updatedImg = document.getElementById("updated-img").value;
// document.getElementById('cat-name') = updatedName;
octopus.updateCat(updatedName, updatedImg);
// catView.render();
});
if (this.isAdmin == 1) {
this.adminPanel.style.display = "block";
// problem here when changed and re render it fetched old name
// this.adminPanel.addEventListener('submit', function() {
// var updatedName = document.getElementById("updated-name").value;
// var updatedImg = document.getElementById("updated-img").value;
// console.log(updatedName + updatedImg);
// // document.getElementById('cat-name') = updatedName;
// octopus.updateCat(updatedName, updatedImg);
// // catView.render();
// });
} else {
this.adminPanel.style.display = "none";
}
}
};
var catViewList = {
init: function () {
// store the DOM element for easy access later
this.catListElem = document.getElementById('side_nav_item');
// render this view (update the DOM elements with the right values)
this.render();
},
render: function () {
var cat, elem, i;
// get the cats we'll be rendering from the octopus
var cats = octopus.getCats();
// empty the cat list
this.catListElem.innerHTML = '';
// loop over the cats
for (i = 0; i < cats.length; i++) {
// this is the cat we're currently looping over
cat = cats[i];
// make a new cat list item and set its text
elem = document.createElement('a');
elem.textContent = cat.name;
// on click, setCurrentCat and render the catView
// (this uses our closure-in-a-loop trick to connect the value
// of the cat variable to the click event function)
elem.addEventListener('click', (function (catCopy) {
return function () {
octopus.setCurrentCat(catCopy);
catView.render();
};
})(cat));
// finally, add the element to the list
this.catListElem.appendChild(elem);
}
}
};
octopus.init();
<!DOCTYPE html>
<html lang="en">
<head>
<link href="css/main.css" rel="stylesheet">
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"> -->
<title>Cat List </title>
</head>
<body>
<div class="main">
<div id="side_nav" class="sidenav" >
<li id="side_nav_item" class="side_nav_item"></li>
</div>
<div id="cat-div">
<h2 id="cat-name"></h2>
<div id="cat-counter"></div>
<img id="cat-image" src="" alt="cute cat">
</div>
<button id="show-admin">Admin</button>
<form id="admin-panel">
<label >Name :</label>
<input type="text" id="updated-name">
<label>Img url :</label>
<input type="text" id="updated-img">
<button id="updateCat" type="submit">Save</button>
</form>
<script src="js/model.js"></script>
</div>
</body>
</html>
I found the solution for my silly issue,
this.adminPanel.addEventListener('submit', function(evt) {
var nameToChange = document.getElementById('updated-name').value;
var imgTOChange = document.getElementById('updated-img').value;
console.log(nameToChange + imgTOChange);
octopus.updateCat(nameToChange + imgTOChange);
evt.preventDefault(); // Here is the trick
});
to close.
Thanks.

Get the width of multiple remote images with javascript (Angular)

I'm trying to solve this issue: I have an array of objects, each containing an image property, which is an absolute url to a remote image.
I have to find the first object with an image larger than 500px, extract it from the array and putting it into another object.
What I've tried to do is to cycle through the array and call a function that loads the image and returns the width, but it doesn't work…
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, loadImages) {
var articles = [
{
"image": "http://i.res.24o.it/images2010/logo.gif"
},
{
"image": "http://www.avvenire.it/Commenti/PublishingImages/ImmaginiArticolo/Originali/gispponema_47548148.jpg"
},
{
"image": "http://i.dailymail.co.uk/i/pix/2012/03/07/article-2111440-1211004C000005DC-146_1024x615_large.jpg"
},
{
"image": "http://www.brookings.edu/~/media/research/images/w/wa%20we/wealthy002/wealthy002_16x9.jpg"
},
{
"image": "http://www.avvenire.it/Mondo/PublishingImages/ImmaginiArticolo/Originali/oREUVENRIV_47517580.jpg"
}
];
$scope.articles = loadImages.getCover(articles);
})
.factory('loadImages', function(){
function getMeta(url){
var img = new Image();
img.src = url;
img.onload = function(){
return img.width;
};
}
return {
getCover: function(articles) {
var cover = null;
for (var i = 0; i < articles.length; i++) {
if(articles[i].image){
var w = getMeta(articles[i].image);
if(w > 500){
cover = articles[i];
articles.splice(i,0);
}
}
}
return {
cover: cover,
articles: articles
};
}
};
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>{{articles}}!</p>
</body>
</html>
plunkr: http://plnkr.co/edit/tCacRy0jf9WhWreWIK7I
Do you have any suggestion? What am I doing wrong?
Thanks
Thanks to #JamesP comment I tried combining an asynchronous cycle found here (Asynchronous for cycle in JavaScript) and the $q promises in this way. I don't know if it's the best way to do it, but it works.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, loadImages) {
var articles = [
{
"image": "http://placehold.it/200"
},
{
"image": "http://placehold.it/300"
},
{
"image": "http://placehold.it/600"
},
{
"image": "http://placehold.it/700"
},
{
"image": "http://placehold.it/800"
}
];
loadImages.asyncLoop(articles.length, function(loop){
var i = loop.iteration();
loadImages.getMeta(articles[i].image).then(function(r){
var cover = articles[i];
articles.splice(i,1);
$scope.articles = {
cover: cover,
articles: articles
};
}, function(){
loop.next();
})
}, function(){
$scope.articles = articles;
});
})
.factory('loadImages', function($q){
return {
getMeta: function(url){
var deferred = $q.defer();
try{
var img = new Image();
img.src = url;
img.onload = function(){
if(img.width > 500){
deferred.resolve(img.width);
}else{
deferred.reject();
}
}
}catch(e){
deferred.reject(e);
}
return deferred.promise;
},
asyncLoop: function(iterations, func, callback) {
var index = 0;
var done = false;
var loop = {
next: function() {
if (done) {
return;
}
if (index < iterations) {
index++;
func(loop);
} else {
done = true;
callback();
}
},
iteration: function() {
return index - 1;
},
break: function() {
done = true;
callback();
}
};
loop.next();
return loop;
}
};
});

How to get a javascript singleton to return data via $.post?

I would like to create a method on the singleton dp.DatapodManager so that it loads the data once via $.post, then I can use that data by calling methods on the singleton.
The output of the following code is:
111
222
test data
What do I have to do to get dp.DatapodManager.loadDirectly(); to add the contents of the text file to div#content?
<html>
<head>
<title>test load</title>
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('div#content').append('<p>1111</p>');
$('div#content').append('<p>222</p>');
$('div#content').append(dp.DatapodManager.getTestData());
dp.DatapodManager.loadDirectly(function(html) {
$('div#content').append(html);
});
});
var dp = dp || {
VERSION : '0.00.05'
};
dp.DatapodManager = (function() {
return {
loadDirectly: function(callback) {
dp.qsys.loadDataFromExternalWebsite(function(stringBlock) {
var lines = dp.qstr.convertStringBlockToLines(stringBlock);
var html = dp.qstr.appendBrToLines(lines);
callback(html); //never executes, cannot set breakpoint here in firebug
});
callback('<p>this is returned</p>');
},
getTestData: function() {
return 'test data';
}
}
}());
dp.qsys = {
loadDataFromExternalWebsite : function(callback) {
url = 'http://localhost/webs/dpjs/data/data.txt';
var json = '';
(function() {
var json = null;
$.post(url, {}, function(jsonString) {
callback(jsonString);
});
return json;
})();
}
};
dp.qstr = {
convertStringBlockToLines: function(block, trimLines) {
var trimLines = trimLines || true;
var lines = block.split(dp.qstr.NEW_LINE());
if(trimLines && lines.length > 0) {
for(x=0; x<lines.length; x++) {
lines[x] = lines[x].trim();
}
}
return lines;
},
NEW_LINE: function() {
return '\r\n';
},
appendBrToLines: function(lines) {
var r = '';
if(lines.length > 0) {
for(x=0; x<lines.length; x++) {
r += lines[x] + '<br/>';
}
}
return r;
}
};
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>

Categories