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

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];

Related

angular ng-src not working with iframe

I am completely new to angular js and am trying to build a google map widget in Service Portal within ServiceNow that dynamically shows the user's job location. I have a server script that pulls and formats the location:
var gr = new GlideRecord('cmn_location');
gr.addQuery('sys_id', gs.getUser().getLocation());
gr.query();
if(gr.next())
{
var loc = gr.street.getHTMLValue();
}
loc1 = loc.replace(/,/g, "");
loc2 = loc1.replace(/ /g, "+");
data.src = loc2;
And my HTML looks like this:
<div class = "map-container">
<iframe ng-src='https://www.google.com/maps/embed/v1/place?key=AIzaSyCmoLpiJFrdXLLUYsM3PRfPD0zQ0uATAUw&q={{data.src}}'></iframe>
</div>
The iframe and {{data.src}} do not work together. If I take away the iframe portion of the code and replace it with {{data.src}}, the address loads correctly. Also, if I replace {{data.src}} with a real address (i.e. washington+dc), the map shows Washington DC correctly.
Can someone help me troubleshoot this issue?
Thanks!
You can have a function defined in the controller and pass the url to it,
routerApp.controller('AppCtrl', ['$scope','$sce', function($scope,$sce) {
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
HTML
<iframe ng-src="{{trustSrc(https://www.google.com/maps/embed/v1/place?key=AIzaSyCmoLpiJFrdXLLUYsM3PRfPD0zQ0uATAUw&q={{data.src}})}}'></iframe>
demo

cannot manipulate string with angular filter

I am an angular newbie and I study the book "Angular JS by example" and I try to create my own filter. (pp. 93-94).
In my controller this is the string I want to manipulate
procedure: "Assume a position, with feet together .\Slightly bend your knees, .\While in air, bring your legs out .\ As you are moving your legs outward"
and then I sanitise it
$scope.trustedHtml = $sce.trustAsHtml($scope.currentExercise.details.procedure);
Since this is an SPA , the filter is in the description-panel.ejs file, that is inside workout.ejs, that is inside index.ejs
description-panel.ejs has
<div class="panel-body" ng-bind-html ="trustedHtml | myLineBreakFilter"> </div>
workout.ejs has
<div id="video-panel" class="col-sm-3" ng-include="'description-panel.ejs'">
and index.ejs has
<script src="/javascripts/7MinWorkout/filters.js"></script>
filter.js has the filter
angular.module('7minWorkout').filter('myLineBreakFilter', function () {
return function (input) {
var str = input;
var br = "</br></br>";
var position = str.indexOf(".");
var output = [str.slice(0, position), br, str.slice(position)].join('');
return output ;
}
});
The filter should replace all the . with </br></br>.
This does not work and I get no text at all in my front-end. I get this error in the console
TypeError: str.slice is not a function at filters.js:22
Shouldn't basic js stuff like str.slice be supported out of the box? What am I missing?
Thanks
$sce.trustAsHtml() return you an object so slice will not work on it.You can pass that object to $sce.getTrustedHtml(object) to obtain the original value and then can apply slice on it.
angular.module('7minWorkout').filter('myLineBreakFilter', function ($sce) {
return function (input) {
var str = $sce.getTrustedHtml(input);
var br = "</br></br>";
var position = str.indexOf(".");
var output = [str.slice(0, position), br, str.slice(position)].join('');
return $sce.trustAsHtml(output) ;
}
});
Try this add this before the splice
str.toString();
str.splice(//pass parameters);

Angularize SharePoint Client Side Taxonomy Picker

The Patterns and Practices team has released a client side taxonomy picker for use when integrating with SharePoint. It works well, but uses jQuery and my SharePoint App is built in Angular... which seems to be a growing trend. I would like to leverage the client side taxonomy picker in Angular and was unsure of how best to achieve this. Here is a link to the component: https://github.com/OfficeDev/PnP/tree/dev/Components/Core.TaxonomyPicker
I am thinking it would be a directive, or is there a non-directive manner to replace (aka, how does Angular manage a replace/initialization) as they are doing here:
HTML:
<input type="hidden" id="taxPickerGeography" />
jQuery Function that gets the Current Context and creates the Taxonomy Picker
$(document).ready(function () {
var context;
context = SP.ClientContext.get_current();
$('#taxPickerGeography').taxpicker({
isMulti: false,
allowFillIn: false,
termSetId: '89206cf2-bfe9-4613-9575-2ff5444d1999'
}, context);
});
I don't need the script loading components as illustrated in the example provided by the PnP team, as I have these already embedded in my App.
Given the challenges of making a "responsive" Managed Metadata field, I built the following using the JavaScript Object Model to retrieve terms and then push them for use in an Array. This includes retrieving Synonyms.
// Query Term Store and get terms for use in Managed Metadata picker stored in an array named "termsArray".
var termsArray = [];
function execOperation() {
// Current Context
var context = SP.ClientContext.get_current();
// Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
// Term Stores
var termStores = taxSession.get_termStores();
// Name of the Term Store from which to get the Terms. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("TermStoreName");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("TermSetGUIDHere");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(function () {
var termEnumerator = terms.getEnumerator();
while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();
var guid = currentTerm.get_id();
var guidString = guid.toString();
var termLabel = currentTerm.get_name();
// Get labels (synonyms) for each term and push values to array
getLabels(guid, guidString, termLabel);
}
// Set $scope to terms array
$scope.$apply(function () {
$scope.termsArray = termsArray;
});
}, function (sender, args) {
console.log(args.get_message());
});
// Get labels (synonyms) for each term and push values to array
function getLabels(termguid, guidString, termLabel) {
var clientContext = SP.ClientContext.get_current();
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(clientContext);
var termStores = taxSession.get_termStores();
// The name of the term store. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("TermStoreName");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("TermSetGUIDHere");
var term = termSet.getTerm(termguid);
var labelColl = term.getAllLabels(1033);
clientContext.load(labelColl);
clientContext.executeQueryAsync(function () {
var labelEnumerator = labelColl.getEnumerator();
var synonyms = "";
while (labelEnumerator.moveNext()) {
var label = labelEnumerator.get_current();
var value = label.get_value();
synonyms += value + " | ";
}
termsArray.push({
termName: termLabel,
termGUID: guidString,
termSynonyms: synonyms
});
}, function (sender, args) {
console.log(args.get_message());
});
}
};
// Execute function
execOperation();

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.

jQuery: looping array to compile url get variables and values

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.

Resources