jQuery: looping array to compile url get variables and values - arrays

I have an array in jQuery, and I'm using $.each() to loop through the array. I'm trying to find a way to compile a URL link using the values in the array
var selectArr = ["numbers123", "more_array_values", "etc", "more"];
$.each(selectArr,function(k,v){
k++;
alert('fid'+k+'='+v);
});
This works,
But I would like to somehow get it so it'll be like
var url = fid1=numbers123&fid2=more_array_values&fid3=etc ...
This way, I can use url and append it to a <a href=''>
Thanks!

With some creative application of jQuery.map and the array method .join:
var url = $.map(selectArr, function(v,k) {
// encodeURIComponent makes the value "URL safe"
return 'fid' + (k + 1) + '=' + encodeURIComponent(v);
}).join('&');

Try this
var selectArr = ["numbers123", "more_array_values", "etc", "more"];
var parts = [];
$.each(selectArr,function(k,v){
parts.push('fid'+(k+1)+'='+v)
});
var url = parts.join('&');
Demo: Fiddle
You can clean up the answer by using the jQuery.map function as Felix said
I would recommend using that method over mine.

Related

angular.fromJson not working properly

The code is as follows
var taskString = window.localStorage['tasks'];
if(taskString) {
var tasks = angular.fromJson(taskString);
console.log(tasks);
}
I had a json format string stored in the window.localStorage['tasks'], which is like this
[{"title":"a"},{"title":"b"},{"title":"c"}]
so that the var taskString would be exactly [{"title":"a"},{"title":"b"},{"title":"c"}]
in the code I tried to parse this string into a json array tasks, and the array should contain three objects with the title attribute set separately as a, b and c
but the problem here is, after the execution of angular.fromJson(taskString), I print the array out to the console, and in the array the titles become b,c, and undefined
Is this a bug of that funciton? Or did I mistankenly do something I shouldn't have in my code?
Thanks
It seems to work fine. Look at the following example snippet. I emulated localStorage as storage.
Check for any silly mistakes or if you are setting it properly.
var storage = {
setItem: function(name, item) {
this[name] = item
}
}
storage.setItem('tasks', '[{"title":"a"},{"title":"b"},{"title":"c"}]')
var taskString = storage['tasks'];
if (taskString) {
var tasks = angular.fromJson(taskString);
console.log(tasks);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
var json = '[{"title":"a"},{"title":"b"},{"title":"c"}]';
var obj = angular.fromJson(json);
console.log(obj);
Works fine for me, below is the fiddle:
http://jsfiddle.net/n8ezb7sg/89/

Use constant property to build another property inside the same constant angularjs

In short my problem is this: I want to use angular constant functionality to save values that I will need in my app. I was wandering if one could build a property using the value of another property of the same constant. Like this:
app.constant("url", {
basicUrl: "/svc",
managementPanel: basicUrl + "/managemnent.html"
// and so on...
});
Is there any way one can achieve this? I tried using the "this" keyword but it referenced the window object.
You can put it all to function:
(function() {
var constant = {};
constant.base = 'base';
constant.nested = constant.base + '/nested';
constant.nested2 = constant.nested + '/nested2';
app.constant('test', constant)
})();
You will need to use a factory instead of the constant shorthand for this.
app.factory("url", function() {
var url = {};
url.basicUrl = "/svc";
url.managementPanel = url.basicUrl + "/managemnent.html";
return url;
})

How to append a new value to an item within an array in Firebase?

Within Firebase, I have a list of 'ideas.' If a user presses a button associated with the idea, I'd like a value to be appended to that idea under an attribute called 'newValue.'
For example, the below html, uses ng-repeat to show the array of ideas and creates an associated button called 'Append Value.' I want a new value to be appended to the idea's attribute called 'newValue' every time a user presses 'Append Value.'
<body ng-controller="ctrl">
<table>
<tr class="item" ng-repeat="(id,item) in ideas">
<td>{{item.idea}}</td>
<td><input ng-model="newValue"></td>
<td><button ng-click="ValueAppend(id,newValue)">Append Value</button></td>
</tr>
</table>
</body>
Below is my attempt to create this function.
var app = angular.module("app", ["firebase"]);
app.factory("Ideas", ["$firebase", function($firebase) {
var Ref = new Firebase('https://crowdfluttr.firebaseio.com/');
var childRef = Ref.child('ideas');
return $firebase(childRef).$asArray();
}]);
app.controller("ctrl", ["$scope","Ideas", function($scope,Ideas) {
$scope.ideas = Ideas;
$scope.idea = "";
$scope.ValueAppend = function (id,newValue) {
var URL = "https://crowdfluttr.firebaseio.com/ideas/" + id + "newValue";
var IdeaRef = new Firebase(URL);
var IdeaData = $firebase(IdeaRef);
$scope.IdeaAttributes = IdeaData.$asArray();
$scope.IdeaAttributes.$add({
newValue: newValue,
timestamp: Date.now()
});
};
}]);
See my codepen for my working example: http://codepen.io/chriscruz/pen/PwZWKG
More Notes:
I understnad that AngularFire provides $add() and $save() to modify this array, but how could I use these methods so that I can add a new 'string' under an item in an array.
I'm not sure if these are your problems, but they are two typoes of mistakes in the code above and the codepen: typos and conceptual.
Typos
You forgot to inject $firebase into the controller, which leads to:
"ReferenceError: $firebase is not defined"
Solution is simply of course:
app.controller("ctrl", ["$scope","Ideas", "$firebase", function($scope,Ideas,$firebase) {
In addition you seem to be missing a slash before newValue, which means that you're trying to create a new idea instead of adding the value to an existing one. Solution is simple again, add a slash before newIdea as in:
var URL = "https://crowdfluttr.firebaseio.com/ideas/" + id + "/newValue";
If you find yourself making this mistake more often, you might be better server by the child function. Although it typically is a bit more code, it lends itself less to this typo of typo. Creating the ref to the newValue node becomes:
var URL = "https://crowdfluttr.firebaseio.com/ideas/";
var IdeaRef = new Firebase(URL).child(id).child("newValue");
Conceptual
With those trivial typos out of the way, we can focus on the real problem: which is easiest to see if you console.log the URL that you generate:
https://crowdfluttr.firebaseio.com/ideas/0/newValue
Yet if you look up the same data in the Firebase forge (by going to https://crowdfluttr.firebaseio.com/ideas/ in your browser), you'll see that the correct URL is:
https://crowdfluttr.firebaseio.com/ideas/-JbSSmv_rJufUKukdZ5c/newValue
That '0' that you're using comes from the id and it is the index of the idea in the AngularJS array. But it is not the key that Firebase uses for this idea. When AngularFire loads your data with $asArray it maps the Firebase keys to Angular indexes. We need to perform the reverse operation to write the new value to the idea: we need to map the array index (in id) back to the Firebase key. For that you can call [$keyAt(id)][1]. Since you keep the array of ideas in Ideas, it is simply:
var URL = "https://crowdfluttr.firebaseio.com/ideas/";
var IdeaRef = new Firebase(URL).child(Ideas.$keyAt(id)).child("newValue");
So the controller now becomes:
app.controller("ctrl", ["$scope","Ideas", function($scope,Ideas) {
$scope.ideas = Ideas;
$scope.idea = "";
$scope.ValueAppend = function (id,newValue) {
var URL = "https://crowdfluttr.firebaseio.com/ideas/";
var IdeaRef = new Firebase(URL).child(Ideas.$keyAt(id)).child("newValue");
var IdeaData = $firebase(IdeaRef);
$scope.IdeaAttributes = IdeaData.$asArray();
$scope.IdeaAttributes.$add({
newValue: newValue,
timestamp: Date.now()
});
};
}]);
I quickly gave it a spin in your codepen and this seems to work.

protractor return array of values from repeater

I am looking for an easy way to return an array of values from protractor's all.(by.repeater)
Basically, I just want an easy way to make an array of usernames given a repeater like user in users.
Right now I'm building it like this:
allUsers = element.all(by.repeater('user in users').column('user.username')).then(function(array){
var results = []
var elemLength = array.length
for(var n = 0; n < elemLength; n++){
array[n].getText().then(function(username){
results.push(username)
})
}
return results
});
expect(allUsers).toContain(newUser)
Is there a more concise, reusable way to do this built into protractor/jasmine that I just can't find?
AS alecxe said, use map to do this. This will return a deferred that will resolve with the values in an array, so if you have this:
var mappedVals = element.all(by.repeater('user in users').column('user.username')).map(function (elm) {
return elm.getText();
});
It will resolve like this:
mappedVals.then(function (textArr) {
// textArr will be an actual JS array of the text from each node in your repeater
});
I've successfully used map() for this before:
element.all(by.repeater('user in users').column('user.username')).map(function (elm) {
return elm.getText();
});
When I researched the topic I took the solution from:
protractor - how to get the result of an array of promises into another array

Angular How to get the video ID from a full YouTube URL

In my data object I have a full YouTube URL (http://www.youtube.com/watch?v=kJ9g_-p3dLA).
In my partial I need to extract the video ID from this string (kJ9g_-p3dLA). I'm trying not to resort to running through all my data when the app starts and extracting the video ID through that way.
I'm looking for a filter or a directive that I can feed the full YouTube ID to which will return the video ID. Anyone?
Ended up writing my own filter for this:
app.filter("GetYouTubeID", function ($sce) {
return function (text) {
var video_id = text.split('v=')[1].split('&')[0];
return video_id;
}
})
Can be used in a partial like so:
{{content.complete_youtube_url | GetYouTubeID}}
<button onclick="myFunction()">Try it</button>
<p id = "demo" />
<script>
function myFunction() {
var url= "http://www.youtube.com/watch?v=kJ9g_-p3dLA"; //sample url
var res = str.split("http://www.youtube.com/watch?").splice("1");
document.getElementById("demo").innerHTML = url;
}
</script>
You could use regular expressions, which have no dependencies on Angular.
Note that I'm not a regex expert so my expression may not be perfect.
var regex = new RegExp(/(?:\?v=)([^&]+)(?:\&)*/);
var url = "http://www.youtube.com/watch?v=kJ9g_-p3dLA";
var matches = regex.exec(url);
var videoId = matches[1]; // kJ9g_-p3dLA
That regex will capture a group between ?v= and & (the & is optional).
Test with explode function of PHP
$youtubre_url = "http://www.youtube.com/watch?v=kJ9g_-p3dLA";
$array_id = explode("=",$youtubre_url);
$id = $array_id[1];

Resources