Hi i have been trying to get into angular.j. I have tried the following code. But the console.log() not seems to be working. Anything am missing?? like angular concepts or something?
var foodshareModule= angular.module('food',['ui.router','ngResource']);
console.log("Main file getting included");
foodshareModule.controller("personController", function($scope) {
console.log($scope);
$scope.firstName = "John";
$scope.lastName = "Doe";
console.log($scope.firstName);
console.log($scope.lastName);
});
foodshareModule.controller('scratchListController', function($scope,$state,Notes){
console.log("working");
$scope.scratchpad =Food.query();
$scope.deleteScratch = function (scratch,flag) {
if(flag === 0) { //Checks if Bulk delete or single delete
if(confirm("You Clicked DELETE !! Are you sure ?")) {
scratch.$delete(function() { //Single delete
window.location.href = 'http://localhost:1337';
});
}
}
else { //Bulk delete
scratch.$delete(function() {
window.location.href = 'http://localhost:1337';
});
}
}
$scope.emptyScratchpad = function () {
var ask = false;
if (confirm ("You are about Empty Scratchpad. Sure ????")) {
ask = true;
}
if(ask === true) {
for (var i = 0; i < $scope.scratchpad.length; i++) {
$scope.deleteScratch($scope.scratchpad[i],1);
}
}
}
})
foodshareModule.factory('Food', function($resource) {
return $resource('http://localhost:1337/Food:id', { id: '#_id' }, {
update: {
method: 'PUT'
}
});
});
Any help would be appreciated. Thanks in advance.
By looking at you code seems like you injected wrong dependency in scratchListController, It should be Food instead of Notes
Code
foodshareModule.controller('scratchListController', function($scope, $state, Food) { //you were added Notes, but there should be Food
console.log("working");
//..other code here
})
var app = angular.module('myApp',[])
.factory('Food', function($resource) {
return $resource('http://localhost:1337/Food:id', { id: '#_id' }, {
update: {
method: 'PUT'
}
});
})
.controller("personController", function($scope) {
console.log($scope);
$scope.firstName = "John";
$scope.lastName = "Doe";
console.log($scope.firstName);
console.log($scope.lastName);
})
.controller('scratchListController', function($scope){
console.log("working");
$scope.deleteScratch = function (scratch,flag) {
if(flag === 0) { //Checks if Bulk delete or single delete
if(confirm("You Clicked DELETE !! Are you sure ?")) {
scratch.$delete(function() { //Single delete
window.location.href = 'http://localhost:1337';
});
}
}
else { //Bulk delete
scratch.$delete(function() {
window.location.href = 'http://localhost:1337';
});
}
}
$scope.emptyScratchpad = function () {
var ask = false;
if (confirm ("You are about Empty Scratchpad. Sure ????")) {
ask = true;
}
if(ask === true) {
for (var i = 0; i < $scope.scratchpad.length; i++) {
$scope.deleteScratch($scope.scratchpad[i],1);
}
}
}
});
Here is your solution. It shows working in the console.
Related
I'm trying to create a simple code verification that checks to code value on key up event and while it's checks - it should show a spinner - but when the timeout has ended then it should displays a markup accordingly (invalid or check mark).
Here is the controller
angular.module("app", []);
angular.module("app").controller("MainController", function ($scope, $timeout) {
$scope.searchStr = "";
$scope.arrResults = [];
$scope.valCode = "666666";
$scope.isShowSpinner = false;
$scope.errorMsg = "";
$scope.isSuccess = false;
$scope.checkCode = function () {
let isError = false;
$timeout.cancel(debounce);
if ($scope.codeArr.join("") == $scope.valCode) {
console.log($scope.codeArr.join(""));
}
if ($scope.codeArr.join("").length == 6) {
$scope.isShowSpinner = true;
var debounce = $timeout(function () {
// debugger;
$scope.errorMsg = "";
$scope.isSuccess = false;
if ($scope.codeArr.join("") != $scope.valCode) {
isError = true;
$scope.errorMsg = "Invalid Code";
}
}, 2000);
$timeout(function () {
$scope.isShowSpinner = false;
if ($scope.errorMsg.length) {
$scope.isSuccess = false;
} else {
$scope.isSuccess = true;
}
}, 50);
}
};
angular.element(document).ready(function () {
$(document).ready(function () {
var body = $("body");
$("body input").on("input", function (e) {
let t = $(e.target);
let sib = t.next("input");
if (isNaN(parseInt(this.value))) {
e.preventDefault();
this.value = null;
return false;
} else {
if (!sib || !sib.length) {
sib = body.find("input").eq(0);
}
sib.select().focus();
return true;
}
});
function getSmsValue(e) {
let isError = false;
e.preventDefault();
var debounce = null;
smsCharsArr = [];
$(".sms-input").each(function () {
let smsValue = this.value;
if (!!smsValue && smsValue !== "") {
smsCharsArr.push(smsValue);
$scope.codeArr = smsCharsArr;
}
});
}
body.on("blur", "input", getSmsValue);
});
});
});
Here is the markup of the indications :
<div ng-if="isShowSpinner" class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
<div ng-if="isSuccess">
<span><i class="fa fa-check"></i></span>
</div>
</div>
<div ng-if="errorMsg.length" class="row">
<h1>{{errorMsg}}</h1>
</div>
So when there are 6 digis - there is a debounce of 2 second to check if the code is correct - while it's checks i want to show the spinner - but when the timeout had ended - i want to hide the spinner and show the results - "invalid" text or "check" icon....
The correct code is 666666 ,
Here is an example
Thanks
Here is my problem
I am trying to create a button that calls a directive function which then activates the google place 'place_changed' event that is assigned to the directive. If the getPlace() function doesn't return a result e.g. var result = scope.gPlace.getPlace(); then I want force a place prediction by doing the following.
if( result === undefined ) {
result = { name: element.val() }
}
however the problem is that this code will work when the page is first loaded but subsequent attempts will assign the var result to the previous text that was entered. e.g. Type "Adelaide" and click on the button equals successful process however now type melbourne and click on the button will still equal "Adelaide"
'use strict';
angular.module( "ngAutocomplete", [])
.directive('ngAutocomplete', function() {
return {
require: 'ngModel',
scope: {
ngModel: '=',
options: '=?',
details: '=?',
setFn: '&'
},
link: function(scope, element, attrs, controller) {
//options for autocomplete
var opts
var watchEnter = false
//convert options provided to opts
var initOpts = function() {
opts = {}
if (scope.options) {
if (scope.options.watchEnter !== true) {
watchEnter = false
} else {
watchEnter = true
}
if (scope.options.types) {
opts.types = []
opts.types.push(scope.options.types)
scope.gPlace.setTypes(opts.types)
} else {
scope.gPlace.setTypes([])
}
if (scope.options.bounds) {
opts.bounds = scope.options.bounds
scope.gPlace.setBounds(opts.bounds)
} else {
scope.gPlace.setBounds(null)
}
if (scope.options.country) {
opts.componentRestrictions = {
country: scope.options.country
}
scope.gPlace.setComponentRestrictions(opts.componentRestrictions)
} else {
scope.gPlace.setComponentRestrictions(null)
}
}
}
if (scope.gPlace == undefined) {
scope.gPlace = new google.maps.places.Autocomplete(element[0], {});
}
google.maps.event.addListener(scope.gPlace, 'place_changed', function() {
var result = scope.gPlace.getPlace();
//hack to make sure we have an object to pass to ensure we can get results from the called function activateGetPlace
if( result === undefined ) {
result = { name: element.val() }
}
console.log("the result", result);
if (result !== undefined) {
if (result.address_components !== undefined) {
scope.$apply(function() {
scope.details = result;
controller.$setViewValue(element.val());
});
}
else {
if (watchEnter) {
getPlace(result)
}
}
}
})
//function to get retrieve the autocompletes first result using the AutocompleteService
var getPlace = function(result) {
var autocompleteService = new google.maps.places.AutocompleteService();
if (result.name.length > 0){
autocompleteService.getPlacePredictions(
{
input: result.name,
offset: result.name.length,
types: opts.types,
componentRestrictions: opts.componentRestrictions
},
function listentoresult(list, status) {
if(list == null || list.length == 0) {
scope.$apply(function() {
scope.details = null;
});
} else {
var placesService = new google.maps.places.PlacesService(element[0]);
placesService.getDetails(
{'reference': list[0].reference},
function detailsresult(detailsResult, placesServiceStatus) {
if (placesServiceStatus == google.maps.GeocoderStatus.OK) {
scope.$apply(function() {
controller.$setViewValue(detailsResult.formatted_address);
element.val(detailsResult.formatted_address);
scope.details = detailsResult;
//on focusout the value reverts, need to set it again.
var watchFocusOut = element.on('focusout', function(event) {
element.val(detailsResult.formatted_address);
element.unbind('focusout')
})
});
}
}
);
}
});
}
}
controller.$render = function () {
var location = controller.$viewValue;
element.val(location);
};
//watch options provided to directive
scope.watchOptions = function () {
return scope.options
};
scope.$watch(scope.watchOptions, function () {
initOpts()
}, true);
scope.activateGetPlace = function() {
google.maps.event.trigger(scope.gPlace, 'place_changed');
}
scope.setFn({theDirFn: scope.activateGetPlace});
}
};
});
var mechanicsearch = angular.module('mechanicsearch', ['ngRoute','ngResource','ngAutocomplete']),
radiusOptions = [];
mechanicsearch.run(function($rootScope) {
$rootScope.$on('handleActiveJobsPanel', function(event, args) {
$rootScope.$broadcast('activateJobsPanel', args);
});
$rootScope.$on('handleActiveFinalise', function(event, args) {
$rootScope.$broadcast('activateFinalisePanel', args);
});
$rootScope.$on('handleActiveSearch', function(event, args) {
$rootScope.$broadcast('activateSearchPanel', args);
});
});
mechanicsearch.filter('htmlToPlaintext', function() {
return function(text) {
return text ? String(text).replace(/<[^>]+>/gm, '') : '';
};
});
// mechFactory service
mechanicsearch.factory('mechFactory', function($resource,$window) {
var mechanics = [];
var jobs = [];
var addMechanic = function(mechanic){
mechanics.push(mechanic);
};
var getAllMechanics = function(){
return mechanics;
};
var removeAllMechanics = function() {
mechanics = [];
}
var addJob = function(job) {
jobs.push(job);
}
var getAllJobs = function() {
return jobs;
}
var removeAllJobs = function() {
jobs = [];
}
return {
getMechanics: function(location,radius) {
return $resource('/ajax/api.cfm?api=mechanic&function=getMechanicByLocation&lat=:lat&lng=:lng&radius=:radius' ).get({lat:location.lat,lng:location.lng,radius:radius});
},
getJobs: function() {
return $resource('/ajax/api.cfm?api=job&function=getJobsAssignedtoWorkshop' ).get();
},
sendMechanicsJobNotifications: function(mechanics, jobs) {
return $resource('/ajax/api.cfm?api=job&function=sendMechanicsJobNotifications&mechanics=:mechanics&jobs=:jobs' ).get({mechanics:mechanics.toString(),jobs:jobs.toString()});
},
addMechanic: addMechanic,
removeAllMechanics: removeAllMechanics,
getAllMechanics: getAllMechanics,
addJob: addJob,
removeAllJobs: removeAllJobs,
getAllJobs: getAllJobs
}
});
mechanicsearch.controller('SearchCtrl', ['$timeout', '$scope', '$window', '$location', '$routeParams', 'filterFilter', 'mechFactory', '$resource', '$element',
function ($timeout, $scope, $window, $location, $routeParams, filterFilter, mechFactory, $resource, $element) {
$scope.place = {};
$scope.place.address = null;
$scope.place.lat = null;
$scope.place.lng = null;
$scope.radius = 25;
$scope.mechanics = [];
$scope.selection = [];
$scope.alert = null;
$scope.showSearchPanel = true;
//Helper method to get selected mechanics
$scope.selectedMechanics = function selectedMechanics() {
filterFilter($scope.mechanics, { selected: true })
};
//allow mechanic checkbox to select/deselect on click
$scope.toggleMechanicSelect = function(mechanic) {
mechanic.selected = !mechanic.selected;
}
$scope.goToJobListing = function() {
$scope.showSearchPanel = false;
mechFactory.removeAllMechanics();
for( var i in $scope.selection ) {
mechFactory.addMechanic($scope.selection[i]);
}
$scope.$emit('handleActiveJobsPanel');
}
// watch mechanics for changes
$scope.$watch('mechanics|filter:{selected:true}', function (nv) {
$scope.selection = nv.map(function (mechanic) {
return mechanic.objectid;
});
}, true);
//watch the returning google autocomplete details object
$scope.$watch('details', function() {
if( $scope.details !== undefined && $scope.details !== null ) {
$scope.place.address = $scope.details.formatted_address;
$scope.place.lat = $scope.details.geometry.location.lat();
$scope.place.lng = $scope.details.geometry.location.lng();
}
});
// watch the $scope.place data for changes
$scope.$watchCollection('place', function() {
if( $scope.place.lat !== null || $scope.place.lng !== null ) {
$scope.getMechanics();
}
});
$scope.$watch('radius', function() {
if( Number.isInteger(parseInt($scope.radius)) ){
$scope.getMechanics();
}
});
$scope.setDirectiveFn = function(directiveFn) {
$scope.directiveFn = directiveFn;
};
$scope.getMechanics = function() {
mechFactory.getMechanics($scope.place, $scope.radius).$promise.then(
function successfulResult (mechanicsData) {
if (!mechanicsData || !mechanicsData.data.length){
$scope.alert = 'Sorry, no mechanic found in "' + $scope.place.address + '" with radius of ' + $scope.radius + '.';
$scope.mechanics = [];
$scope.selection = [];
} else {
$scope.alert = mechanicsData.data.length + ' mechanic(s) found in "' + $scope.place.address + '" with radius of ' + $scope.radius + ' km.';
$scope.mechanics = mechanicsData.data;
$scope.selection = [];
}
}, function failedResult (err) {
$scope.alert = err.message;
});
};
//display panel once we have recieved the event
$scope.$on('activateSearchPanel', function(event, args) {
$scope.mechanics = [];
$scope.selection = [];
$scope.alert = null;
$scope.showSearchPanel = true;
$scope.place = {};
$scope.radius = 25;
});
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-route.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-resource.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCmN0htBqG3DGo04KKKzC9srgIrhP0Dq5o&libraries=places"></script>
<div id="mechanicsearch" data-ng-app="mechanicsearch">
<div data-ng-controller="SearchCtrl" ng-show="showSearchPanel">
<aside class="workshopsearch" >
<form method="post" class="form-inline" role="form">
<div class="row">
<div class="col-sm-6 form-group input-group-lg">
<input type="text" id="geoSearch" ng-model="autocomplete" class="form-control" ng-autocomplete options="{ types: 'geocode', country: 'au', watchEnter: true }" details="details" set-fn="setDirectiveFn(theDirFn)" />
</div>
<div class="col-sm-6 input-group input-group-lg">
<input type="text" class="form-control" name="radius" id="radius" placeholder="Radius" data-ng-model="radius">
<span class="input-group-btn"><button class="btn btn-go" ng-click="directiveFn()">Go</button</span>
</div>
</div>
</form>
</aside>
</div>
</div>
}
Why are you using element.val() when you have an ngModel bound to the input? Why not use scope.ngModel instead?
I am using wordpress as a backend for an app and I want to use infinite scroll but I am having trouble concatenating articles.
I am calling the service using a factory:
.factory('Worlds', function ($http) {
var worlds = [];
storageKey = "worlds";
function _getCache() {
var cache = localStorage.getItem(storageKey );
if (cache)
worlds = angular.fromJson(cache);
}
return {
all: function () {
return $http.get("http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=10").then(function (response) {
worlds = response.data;
console.log(response.data);
return worlds;
});
},
GetNewPosts: function () {
return $http.get("http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=2").then(function (response) {
worlds = response.data;
console.log(response.data);
return worlds;
});
},
get: function (worldId) {
if (!worlds.length)
_getCache();
for (var i = 0; i < worlds.length; i++) {
if (parseInt(worlds[i].ID) === parseInt(worldId)) {
return worlds[i];
}
}
return null;
}
}
})
and my controller looks like this:
.controller('WorldCtrl', function ($scope, $stateParams, $timeout, _, Worlds) {
$scope.worlds = [];
Worlds.all().then(function (data){
$scope.worlds = data;
window.localStorage.setItem("worlds", JSON.stringify(data));
},
function (err) {
if(window.localStorage.getItem("worlds") !== undefined) {
$scope.worlds = JSON.parse(window.localStorage.getItem("worlds"));
}
}
);
$scope.loadMore = function() {
Worlds.GetNewPosts().then(function (worlds){
var loadedIdss = _.pluck($scope.worlds, 'id');
var newItemss = _.reject(worlds, function (item){
return _.contains(loadedIdss, item.id);
});
$scope.worlds = newItemss.concat($scope.worlds);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
})
I am trying to use underscore to ignore the posts that are already loaded, however when i try the infinite scroll it just goes into a loop calling more posts but doesnt add them to my ng-repeat and ionicLoading renders the app useless.
ion-infinite-scroll works with some sort of paginated result and you seem to feed your list with all the results.
Your API should look something like this:
http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=2&filter[page]=1
notice I've added a page filter.
and your service responsible to fetch the data should look something like this:
.factory('dataService', function($http) {
return {
GetPosts: function(page, pageSize) {
return $http.get("http://mywebservice/api/test/posts/" + page + "/" + pageSize);
}
};
});
Your controller
.controller('mainController', function($scope, dataService) {
$scope.posts = [];
$scope.theEnd = false;
var page = 0;
var pageSize = 10;
$scope.$on('$stateChangeSuccess', function() {
$scope.loadMore();
});
$scope.loadMore = function(argument) {
page++;
dataService.GetPosts(page, pageSize)
.then(function(result) {
console.log('items fetched: ' + result.data.length);
if (result.data.length > 0) {
angular.forEach(result.data, function(value, key) {
$scope.posts.push(value);
});
}
else {
$scope.theEnd = true;
}
})
.finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
};
})
would initialize an array of objetct - as you're doing - and a boolean which tells the directive ion-infinite-scroll when you've reached the end:
$scope.posts = [];
$scope.theEnd = false;
Then you can have some variables to control the pagination:
var page = 0;
var pageSize = 10;
I start loading when the view is loaded:
$scope.$on('$stateChangeSuccess', function() {
$scope.loadMore();
});
$scope.loadMore then would increment the page number:
page++;
and call the service layer:
dataService.GetPosts(page, pageSize)
when I've reached the end of the stream I would set the variable:
$scope.theEnd = true;
to let the directive know we don't have other items to append.
.finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
finally is always called when the promise is resolved.
Instead of ng-repeat you can use collection-repeat which should be much faster.
You can play with it here.
Try this create a function infiniteScrollCompleteCancelLoadMore and call it when you want to complete the scroll and you have reached the end of your list.
function infiniteScrollCompleteCancelLoadMore() {
$timeout(function () {
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
$rootScope.canLoad = false;
});
});
}
$scope.loadMore = function() {
Worlds.GetNewPosts().then(function (worlds){
var loadedIdss = _.pluck($scope.worlds, 'id');
var newItemss = _.reject(worlds, function (item){
return _.contains(loadedIdss, item.id);
});
$scope.worlds = newItemss.concat($scope.worlds);
infiniteScrollCompleteCancelLoadMore() // CHANGE HERE
});
};
and your HTML
<ion-infinite-scroll on-infinite="loadMore()" ng-if="canLoad" distance="1%"
immediate-check="false"></ion-infinite-scroll>
OR call This is you just want to cancel loadMore loop.
function infiniteScrollComplete() {
$timeout(function () {
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
});
});
}
I have following Angular JS service which is accessing to the cordova media plugin.
MediaSrv.loadMedia(filePath, mediaSuccess, null, status).then(function(media, status, test, status1){
media.play({ numberOfLoops: 999 });
media.setVolume(volume);
$scope.selectedSounds[index].state = 1;
$scope.selectedSounds[index].mediaInstance = media;
$scope.someSoundsArePlaying = true;
});
I would like to ask, how can i do loop playing of the selected file which can be stopped after passing mediaInstance to stop function?
I tried mediaSuccess Callback and status CallBack but it does not work properly.
Service is following:
'use strict';
angular.module('MaxRelax')
.factory('MediaSrv', function($q, $ionicPlatform, $window){
var service = {
loadMedia: loadMedia,
getStatusMessage: getStatusMessage,
getErrorMessage: getErrorMessage
};
function loadMedia(src, onError, onStatus, onStop){
var defer = $q.defer();
$ionicPlatform.ready(function(){
var mediaSuccess = function(){
if(onStop){onStop();}
};
var mediaError = function(err){
_logError(src, err);
if(onError){onError(err);}
};
var mediaStatus = function(status){
console.log(status);
if(onStatus){onStatus(status);}
};
if($ionicPlatform.is('android')){src = '/android_asset/www/' + src;}
defer.resolve(new $window.Media(src, mediaSuccess, mediaError, mediaStatus));
});
return defer.promise;
}
function _logError(src, err){
console.error('media error', {
code: err.code,
message: getErrorMessage(err.code)
});
}
function getStatusMessage(status){
if(status === 0){return 'Media.MEDIA_NONE';}
else if(status === 1){return 'Media.MEDIA_STARTING';}
else if(status === 2){return 'Media.MEDIA_RUNNING';}
else if(status === 3){return 'Media.MEDIA_PAUSED';}
else if(status === 4){return 'Media.MEDIA_STOPPED';}
else {return 'Unknown status <'+status+'>';}
}
function getErrorMessage(code){
if(code === 1){return 'MediaError.MEDIA_ERR_ABORTED';}
else if(code === 2){return 'MediaError.MEDIA_ERR_NETWORK';}
else if(code === 3){return 'MediaError.MEDIA_ERR_DECODE';}
else if(code === 4){return 'MediaError.MEDIA_ERR_NONE_SUPPORTED';}
else {return 'Unknown code <'+code+'>';}
}
return service;
});
Many, many thanks for any help.
EDIT:
Playing of the item is processed by the following method:
$scope.playSelectedItem = function(index) {
try {
var fileName = $scope.selectedSounds[index].file;
var volume = $scope.selectedSounds[index].defaultVolume;
var filePath = "sounds/" +fileName+".mp3";
console.log(filePath);
MediaSrv.loadMedia(
filePath,
function onError(err){ console.log('onError', MediaSrv.getErrorMessage(err)); },
function onStatus(status){ console.log('onStatus', MediaSrv.getStatusMessage(status)); },
function onStop(){ console.log('onStop'); myMedia.play(); }
).then(function(media){
myMedia = media;
media.play({ numberOfLoops: 999 });
media.setVolume(volume);
$scope.selectedSounds[index].state = 1;
$scope.selectedSounds[index].mediaInstance = media;
$scope.someSoundsArePlaying = true;
});
} catch(e) {
alert(JSON.stringify(e));
console.log(e);
$scope.showAlert("Error", "Error during the playing item");
}
};
Stopping:
$scope.stopSelectedItem = function(index) {
try {
var leng = 0;
if($scope.selectedSounds[index].state == 1) {
var mediaInstance = $scope.selectedSounds[index].mediaInstance;
mediaInstance.stop();
$scope.selectedSounds[index].state = 0;
$scope.selectedSounds[index].mediaInstance = "";
myMedia.stop();
}
angular.forEach($scope.selectedSounds, function loadMedia(selectedSound, idx){
if($scope.selectedSounds[idx].state == 1) {
leng ++;
}
});
if(leng <= 0) {
$scope.someSoundsArePlaying = false;
console.log("No sound are playing");
}
if(leng > 0) {
$scope.someSoundsArePlaying = true;
console.log("Some sound are playing");
}
console.log("Leng is:");
console.log(leng);
} catch(e) {
alert(JSON.stringify(e));
console.log(e);
$scope.showAlert("Error", "Cannot stop playing of item");
}
};
EDIT2:
I finally solved it using storing myMedia instance in the simple array.
$scope.playSelectedItem = function(index) {
try {
var fileName = $scope.selectedSounds[index].file;
var volume = $scope.selectedSounds[index].defaultVolume;
var filePath = "sounds/" +fileName+".mp3";
console.log(filePath);
MediaSrv.loadMedia(
filePath,
function onError(err){ console.log('onError', MediaSrv.getErrorMessage(err)); },
function onStatus(status){ console.log('onStatus', MediaSrv.getStatusMessage(status)); },
function onStop(){
console.log('onStop');
if($scope.selectedSounds[index].state == 1) {
console.log('For index ' +index+' is state '+$scope.selectedSounds[index].state);
myMedia[index].play();
}
}
).then(function(media){
myMedia[index] = media;
media.play({ numberOfLoops: 999 });
media.setVolume(volume);
$scope.selectedSounds[index].state = 1;
$scope.selectedSounds[index].mediaInstance = media;
$scope.someSoundsArePlaying = true;
});
} catch(e) {
alert(JSON.stringify(e));
console.log(e);
$scope.showAlert("Error", "Error during the playing item");
}
};
I'm pleased that you find my angular service usefull.
In your sample you seems to mess up with parameter order :
MediaSrv.loadMedia(filePath, mediaSuccess, null, status) vs
function loadMedia(src, onError, onStatus, onStop)
BTW, play parameter numberOfLoops does not seems to work (at least on my nexus4). If you want to loop, you will need to call play() every time the mp3 ends.
Here is a short example :
var myMedia = null;
MediaSrv.loadMedia(
'sounds/1023.mp3',
function onError(err){ console.log('onError', MediaSrv.getErrorMessage(err)); },
function onStatus(status){ console.log('onStatus', MediaSrv.getStatusMessage(status)); },
function onStop(){ console.log('onError'); myMedia.play(); },
).then(function(media){
myMedia = media;
myMedia.play();
});
With this code, your sound should play, forever... To control when your sound should stop, I suggest you to add a control parameter, like this :
var myMedia = null;
var shouldPlay = false;
MediaSrv.loadMedia(
'sounds/1023.mp3',
function onError(err){ console.log('onError', MediaSrv.getErrorMessage(err)); },
function onStatus(status){ console.log('onStatus', MediaSrv.getStatusMessage(status)); },
function onStop(){ console.log('onError'); if(shouldPlay){myMedia.play();} },
).then(function(media){
myMedia = media;
});
function playStart(){
shouldPlay = true;
myMedia.play();
}
function playStop(){
shouldPlay = false;
myMedia.stop();
}
To play multiples files in a loop, you have to store all media references and play them successively. See there :
var shouldPlay = false;
var playingMedia = null;
var soundFiles = ['sounds/1.mp3', 'sounds/2.mp3', 'sounds/3.mp3'];
var mediaInstances = [];
var onPlayStop = function(){
if(shouldPlay){
if(playingMedia === null){
playingMedia = 0;
} else {
playingMedia = (playingMedia+1) % mediaInstances.length;
}
mediaInstances[playingMedia].play();
}
};
for(var i in soundFiles){
MediaSrv.loadMedia(soundFiles[i], null, null, onPlayStop).then(function(media){
mediaInstances.push(media);
});
}
function playStart(){
shouldPlay = true;
onPlayStop();
}
function playStop(){
shouldPlay = false;
mediaInstances[playingMedia].stop();
}
I hope this will helps :D
I have a particular function dependant on a (previously executed) service that will trigger multiple queries to a 3rd party API. This API with cancel the requests if it gets too many of them too quick. Is there a way to set a delay to the $http query?
Here is my $http code:
$scope.getImages = function (title, name) {
$http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json').
success(function(data4) {
$scope.images = data4;
});
}
EDIT Upon request I paste my whole JS (probably I should have done so from the start)
angular.module('myApp', ['ngResource'])
function Ctrl($scope, $http) {
var search = function(name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5').
success(function(data3) {
$scope.clicked = false;
$scope.results = data3.results;
});
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
}
}
$scope.$watch('name', search, true);
$scope.getDetails = function (id) {
$http.get('http://api.discogs.com/artists/' + id).
success(function(data) {
$scope.artist = data;
});
$http.get('http://api.discogs.com/artists/' + id + '/releases?page=1&per_page=10').
success(function(data2) {
$scope.releases = data2.releases;
});
$scope.clicked = true;
$scope.sliding = true;
}
$scope.getImages = function (title, name) {
$http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json').
success(function(data4) {
$scope.images = data4;
});
}
};
I assume you will want to debounce your calls somehow, something simple like this should work. It will make the call every 300ms unless search(name) is called again before it fires.
var debounce = null;
var search = function(name) {
$timeout.cancel(debounce);
if (name) {
debounce = $timeout(function() {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5')
.success(function(data3) {
$scope.clicked = false;
$scope.results = data3.results;
});
},300);
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
}
}