Append '|' after every array element - javascript

I have this JSON & what I want to do is to make genres like this action|adventure|comedy
{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
my component code snippet
data => {
this.movies = data;
var tempArr= data
var genres;
let genresWithPipe=[];
let len= tempArr.length;
for(var i=0; i<len; i++){
genres=tempArr[i].genres+'|';
// console.log(tempArr[i].genres)
for(var j=0;j<genres.length; j++){
if(j<genres.length-1)
genres[j]= genres[j]+'|';
console.log(genres,data);
//genresWithPipe=genres;
}
}
console.log(this.movies,genres)
}
I have tried to do it with the help of for loop in my component but then when I am displaying it in the html with the help of *ngFor then because it's a local variable,it won't show up. If I store array values in a global variable then the variable only store the last array.

You can use map method in order to achieve your requirement and obtain a more cleaner solution.
The map() method creates a new array with the results of calling a
provided function on every element in the calling array.
Also, you can use join method in order to obtain the structure action|adventure|comedy with | delimiter.
let array=[{ "id": 1, "key": "deadpool", "name": "Deadpool", "description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.", "genres": [ "action", "adventure", "comedy" ], "rate": 8.6, "length": "1hr 48mins", "img": "assets/images/movie-covers/deadpool.jpg" }, { "id": 2, "key": "we-are-the-millers", "name": "We're the Millers", "description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.", "genres": [ "adventure", "comedy", "crime" ], "rate": 7, "length": "1hr 50mins", "img": "assets/images/movie-covers/we-are-the-millers.jpg" }];
array=array.map(function(item){
item.genres=item.genres.join('|');
return item;
});
console.log(array);

A good solution with Array.map() has been proposed, here is another option with Array.forEach():
const data = [{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
]
const genres = [];
data.forEach(film => genres.push(film.genres.join("|")));
console.dir(genres);
Note that your data definitely doesn't look like what you put in the code sample, it must be wrapped with [].

Related

concatenate dataLayer for impression tracking because of lazyloading

I want to implement impression tracking on element visibility. I am following the guide of simo ahava
https://www.simoahava.com/analytics/true-view-impressions-google-tag-manager/
Now I cannot replicate that example because it needs to fire all product once into the dataLayer but on my case i am doing lazy loading and have to push the product in batch into the dataLayer. Unfortunately by doing this every time we are pushing some element into the datalayer it will only take the last values of the event push on google tag manager so it is very possible that the product becomes visible but is no more available into the dataLayer.
Here is a more detailed explanation
Step 1 : We have a two push into the data layer for lazy loading purpose
1a. first push as the first portion loads
dataLayer=[];
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [{
"id": "9bdd2",
"name": "Compton T-Shirt",
"price": "44.00",
"brand": "Compton",
"category": "T-Shirts",
"position": 0,
"list": "shirts you may like"
},
{
"id": "239b5",
"name": "Pigzart T-Shirt",
"price": "82.00",
"brand": "Pigzart",
"category": "T-Shirts",
"position": 1,
"list": "shirts you may like"
}
],
}
});
1b. second push due to lazy loading
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}
],
}
});
2 - Now let's say that the customer have an element visibility trigger that happen after the second dataLayer push on the product "Compton T-Shirt". It will not be able to know what are the information
So comes my questions , is there a way to concatenate the eec.impressionView events into a single one on the GTM side or is there a better way to handle this type of problem to be able to capture the impression
What you're encountering is known as "Recursive Merge", so the products you're pushing into the dataLayer merge in with the existing products in the internal data model, rather than being appended to it.
The easiest way to avoid the recursive merge is within your dataLayer push.
Instead of doing a full dataLayer push for your subsequent impressions
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}
],
}
});
It works if you can use this for the subsequent dataLayer pushes.
dataLayer.push(['ecommerce.impressions.push',
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}]);
This will prevent the second push from overwriting the existing values and because you're using visibility triggers there's no need for the repeated event, and everything else will be the same in the data model.
Alternatively you could use a custom HTML tag and fire that on each event to store the impressions in a separate JS object and reference that rather than the dataLayer in your Enhanced Ecommerce setup.

Formatting JSON data retrieved from PostgreSql database

I am trying to display my seed data as JSON when a user visits a certain endpoint. I have two tables, Playlists and Favorites. It is a one to many relationship where a Playlist has many Favorites. The JSON should be formatted like this:
[{
"id": 1,
"playlist_name": "Favorite songs of all time",
"favorites": [{
"id": 1,
"name": "We Will Rock You",
"artist_name": "Queen",
"genre": "Rock",
"rating": 88
}]
}]
The function that I am calling to retrieve data from the database is this:
const connection = require("../connection");
function getAll() {
return connection.select().from('playlists').join('favorites', 'playlists.id', '=', 'favorites.id')
}
module.exports = getAll;
And what I get back when I call this function is this:
[
{
"id": 1,
"playlist_name": "chill_tunes",
"name": "Leo",
"artist_name": "John",
"genre": "Pop",
"rating": 42,
"playlist_id": 1
},
{
"id": 2,
"playlist_name": "good_vibes",
"name": "Dan",
"artist_name": "Deer",
"genre": "Rock",
"rating": 52,
"playlist_id": 1
},
{
"id": 3,
"playlist_name": "hump_day_happiness",
"name": "Nick",
"artist_name": "Legend",
"genre": "Rap",
"rating": 12,
"playlist_id": 2
}
]
I have no idea how to format my JSON data to get it like the code up top. Any help would be greatly appreciated.
You can use reduce
Here idea is
On op object create keys based on playlist id.
If there's already a key we push the new value to favourites
If not than we initialize favourites with {id, playlist_name , favourites:[]} and than push the new value
let arr = [{"id": 1,"playlist_name": "chill_tunes","name": "Leo","artist_name": "John","genre": "Pop","rating": 42,"playlist_id": 1},{"id": 2,"playlist_name": "good_vibes","name": "Dan","artist_name": "Deer","genre": "Rock","rating": 52,"playlist_id": 1},{"id": 3,"playlist_name": "hump_day_happiness","name": "Nick","artist_name": "Legend","genre": "Rap","rating": 12,"playlist_id": 2}]
let final = arr.reduce((op,{id, playlist_name ,name ,artist_name ,genre ,rating , playlist_id}) => {
op[playlist_id] = op[playlist_id] || {id, playlist_name , favourites:[]}
op[playlist_id].favourites.push({id, playlist_id ,name ,artist_name ,genre ,rating})
return op
},{})
console.log(Object.values(final))

coding watson conversation for complex inputs?

I would like to know how can I integrate some coding (python or javascript) in my dialog, in order to avoid the very limited bluemix interface for example for loops, or text mining.
EX : I am creating a pizza chatbot and I need to be able to process this kind of request :
I would like 2 margarita whose one with extra cheese and the other with pepperoni and a regina, with 3 diet cokes and two beers
It is just impossible to do it with bluemix.
If anyone has a solution I would be very grateful.
Thanks
So the first thing to understand is that Conversation has good and bad use cases.
If your user can enter in structured data, then it is better to use a form. Be that in the conversation window (like Watson Virtual Agent), or a form on your site/app.
So your example doesn't look like a good use case.
That said...
With your example it's possible if your main items are entities, and you haver #sys-number system entity enabled. You can then check the entities array to see distance from each other.
Example
Created the following entities.
#PizzaType
#PizzaTopping
#Drinks
When I ask your question, the entities object returns the following:
[
{
"entity": "Drinks",
"location": [
104,
114
],
"value": "diet coke",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
72,
81
],
"value": "Pepperoni",
"confidence": 1
},
{
"entity": "Drinks",
"location": [
123,
128
],
"value": "beer",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
88,
94
],
"value": "Regina",
"confidence": 1
},
{
"entity": "PizzaTopping",
"location": [
46,
52
],
"value": "cheese",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
15,
24
],
"value": "Margarita",
"confidence": 1
},
{
"entity": "sys-number",
"location": [
13,
14
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
},
{
"entity": "sys-number",
"location": [
31,
34
],
"value": "1",
"confidence": 1,
"metadata": {
"numeric_value": 1
}
},
{
"entity": "sys-number",
"location": [
101,
102
],
"value": "3",
"confidence": 1,
"metadata": {
"numeric_value": 3
}
},
{
"entity": "sys-number",
"location": [
119,
122
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
}
]
A summary of that is:
You can see straight away there are some issues there. If the user doesn't mention a number, you have to account for that. Also something like this question would break it as well (unless you cater for it).
I would like margarita pizzas (two).
But the important point is to build your system with representative questions. Your example question may never be asked by an end user, or you can even shape the conversation to prevent such an input.

Facebook Feed on web page infinte scrolling

I am trying to use this plugin to create an infinite scroll effect for Facebook feeds, now I get access to the feed I need through the graph api (fan page wall posts) and I limit it to 10, and even so Facebook supplies a next and previous links to the next or previous 10 posts in the actual json data, but I just can't seem to get this plugin working with it.
Heres an example of the json data:
{
"data": [
{
"id": "393459637370574_326418557474553",
"from": {
"category": "Consulting/business services",
"name": "Global Georgia",
"id": "393459637370574"
},
"to": {
"data": [
{
"name": "Global Georgia Tour",
"start_time": "2012-12-05",
"location": "Republic of Georgia",
"id": "297926606990415"
}
]
},
"message": "What a lovely trip it was!",
"picture": "http://photos-a.ak.fbcdn.net/hphotos-ak-snc7/205700_468134469903090_2092776360_s.jpg",
"link": "https://www.facebook.com/photo.php?fbid=468134469903090&set=oa.462645617136057&type=1&relevant_count=4",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif",
"privacy": {
"value": ""
},
"type": "photo",
"object_id": "468134469903090",
"created_time": 1359555861,
"updated_time": 1359555861,
"likes": {
"data": [
{
"name": "Mareleen du Plessis",
"id": "1382224862"
}
],
"count": 1
},
"comments": {
"count": 0
}
},
{
"id": "393459637370574_333589073411971",
"from": {
"category": "Consulting/business services",
"name": "Global Georgia",
"id": "393459637370574"
},
"story": "Global Georgia shared a link.",
"story_tags": {
"0": [
{
"id": "393459637370574",
"name": "Global Georgia",
"offset": 0,
"length": 14,
"type": "page"
}
]
},
"picture": "http://external.ak.fbcdn.net/safe_image.php?d=AQCwYiOOZnd4DK5_&w=90&h=90&url=http\u00253A\u00252F\u00252Frsa.mfa.gov.ge\u00252FuniInc.php\u00253Fmode\u00253Dimg\u002526src_jpg\u00253Dfiles\u00252Frsa\u00252FPresentation_Credentials_to_President_Jacob_Zuma_of_South_Africa-29.01.2013.jpg\u002526im_new_w\u00253D200",
"link": "http://rsa.mfa.gov.ge/index.php?lang_id=ENG&sec_id=913&info_id=16905",
"name": "News - Embassy of Georgia to the Republic of South Africa",
"caption": "rsa.mfa.gov.ge",
"description": "On January 2013, in Pretoria, the firstAmbassador Extraordinary and Plenipotentiary of Georgia in the Republic of South Africa, Mr Beka Dvali presented his credentials to the President of the Republic of South Africa, H.E. Mr Jacob Zuma. ",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
"privacy": {
"value": ""
},
"type": "link",
"status_type": "shared_story",
"created_time": 1359550985,
"updated_time": 1359550985,
"likes": {
"data": [
{
"name": "Ivan A Meyer",
"id": "100000016287990"
},
{
"name": "Amanda Aldum",
"id": "779374234"
},
{
"name": "Cazz Bouwer",
"id": "100001702505460"
},
{
"name": "Gigi Mikeladze",
"id": "100004658262461"
}
],
"count": 4
},
"comments": {
"count": 0
}
},
{
"id": "393459637370574_450229665031926",
"from": {
"category": "Consulting/business services",
"name": "Global Georgia",
"id": "393459637370574"
},
"story": "Global Georgia shared Embassy of Georgia in the Republic of South Africa's photo.",
"story_tags": {
"0": [
{
"id": "393459637370574",
"name": "Global Georgia",
"offset": 0,
"length": 14,
"type": "page"
}
],
"22": [
{
"id": "340928409306379",
"name": "Embassy of Georgia in the Republic of South Africa",
"offset": 22,
"length": 50,
"type": "page"
}
]
},
"picture": "http://photos-f.ak.fbcdn.net/hphotos-ak-snc7/385189_475566662509219_1872863393_s.jpg",
"link": "https://www.facebook.com/photo.php?fbid=475566662509219&set=a.405386502860569.99241.340928409306379&type=1",
"name": "Timeline Photos",
"caption": "Information on the meeting of the Ambassador of Georgia\r\nwith the National Librarian and Chief Executive Officer\r\nof the National Library of South Africa\r\n\r\nOn 24 January 2013 H.E. Mr Beka Dvali, Ambassador of Georgia held a meeting with Mr John Tsebe, the National Librarian and Chief Executive Officer of the National Library of the Republic of South Africa, and the Chair of the Conference of Directors of National Libraries (CDNL)).\r\nAmbassador of Georgia passed on Mr Tsebe several books to be catalogued as the first ever publications on Georgia at the National Library of South Africa.\r\nDuring the meeting, the parties discussed the possibilities of cooperation between the national libraries of the two countries, the issues of supplying Georgian and Georgia-related books, by the support of the Embassy, to the National Library of South Africa as well as the prospects of hosting by the library a literature event featuring contemporary Georgian author(s). \r\n\r\n24 January 2013\r\nPretoria",
"properties": [
{
"name": "By",
"text": "Embassy of Georgia in the Republic of South Africa",
"href": "https://www.facebook.com/EmbassyOfGeorgia?ref=stream"
}
],
"icon": "http://static.ak.fbcdn.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
"privacy": {
"value": ""
},
"type": "photo",
"status_type": "shared_story",
"object_id": "475566662509219",
"application": {
"name": "Photos",
"id": "2305272732"
},
"created_time": 1359387805,
"updated_time": 1359387805,
"comments": {
"count": 0
}
}
],
"paging": {
"previous": "https://graph.facebook.com/393459637370574/feed?limit=3&date_format=U&access_token=XXXX&since=1359555861&__previous=1",
"next": "https://graph.facebook.com/393459637370574/feed?limit=3&date_format=U&access_token=XXXX&until=1359387804"
}
}
How would I get this functionality working?
Any help/advice greatly appreciated
It looks like you'd have to spend a lot of time wrangling with infinite-scroll.js to get it to do what you want, because it depends on having pagination links in your HTML.
What would probably be easier would be to write your own Javascript to detect when the user is scrolling and automatically load stuff then, based on the next page link in your most recent JSON response.
If you look at the code for jscroll.js (a similar plugin to infinte-scroll, but with code that's a bit simpler) you'll probably a get a good idea of what to look for and when to load new content. Specifically, from line 84:
// Observe the scroll event for when to trigger the next load
function _observe() {
var $inner = $e.find('div.jscroll-inner').first(),
data = $e.data('jscroll'),
iContainerTop = parseInt($e.css('paddingTop')) + parseInt($e.css('borderTopWidth')),
iTopHeight = _isWindow ? _$scroll.scrollTop() : $e.offset().top,
innerTop = $inner.length ? $inner.offset().top : 0,
iTotalHeight = Math.ceil(iTopHeight - innerTop + _$scroll.height() + iContainerTop),
nextHref = $.trim(data.nextHref + ' ' + _options.contentSelector);
if (_checkNextHref(data) && !data.waiting && iTotalHeight + _options.padding >= $inner.outerHeight()) {
_debug('info', 'jScroll:', $inner.outerHeight() - iTotalHeight, 'from bottom. Loading next request...');
return _load();
}
}
Looking at the documentation, It seems to allow a functionality where it calls the link in the href via AJAX and returns the response to you.
If you make an initial call on pageload to populate your initial feed, then create a display: none link with something like:
#nextLink {
display: none;
}
and give it a href of the data['paging']['next'] then you could initialise the infinite scroll with something like:
$('.feedContainer').infinitescroll({
// other options
nextSelector: "a#nextLink",
dataType: 'json',
appendCallback: false
}, function(json, opts) {
// Update your next link to point to the next page
$('#nextLink').attr('href',json['data']['paging']['next']);
// Add your new feed rows here
var htmlStr = '<li>FeedContent</li>';
// Append it to the container
$('.feedContainer').append(htmlStr);
});
Use dataType 'jsonp' if it supports it.
That should roughly give you what you're looking for!

Cannot access array objects when that array is itself an attribute of an object

I am unable to access an array of objects that is itself an attribute of a larger object.
console.log(skillprofiles);
console.log(skillprofiles.skills);
The above statements return an array of two objects that each have an attribute that is a, seemingly, valid array of objects ("skills" in this example).
I am unable to access the "skills" array attribute. The data I am ultimately trying to get at is the "item_name" attribute. As far as I know, that should be accessible via:
skillprofiles[0].skills[0].item_name
Interestingly enough, verifying the type of the "skills" attribute with "typeof" returns "object" instead of array. This could be because I am transferring an array of objects from one object to another earlier in my code. I thought I was doing this properly and seemed to have confirmed that by my logging statements.
UPDATE with actual data:
[{
"skillprofile_id": 144,
"skillprofile_name": " On-boarding",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "3. On-boarding a New Hire - Day 1",
"skill_type": "activity",
"object_id": 68,
"duration": "8:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "4. On-boarding Checklist",
"skill_type": "activity",
"object_id": 67,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}, {
"skillprofile_id": 143,
"skillprofile_name": " Setting Up Systems",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "1. Office Organization",
"skill_type": "activity",
"object_id": 65,
"duration": "4:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "2. Welcome to the Team Documents",
"skill_type": "activity",
"object_id": 66,
"duration": "2:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "3. Welcome Documents: Feedback ",
"skill_type": "activity",
"object_id": 150,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}]
UPDATE 2:
Given the responses so far, it seems that I should be able to run the following:
$.each(skillprofiles, function(){
console.log(this.skills)
});
I can do this from the console, but the console statements come back as "undefined" when run from my code
In your first block of code, skills is directly a child of skillprofiles. Whereas in the second one, you write skillprofiles[o].skills. If the first one works, maybe your code should be:
skillprofiles.skills[0].item_name
With that data structure, the proper access would be:
skillprofiles[i].skills[j].item_name
You can see it work here: http://jsfiddle.net/jfriend00/wPLZZ/
skillprofiles is an array of objects so you get an object from the array with:
skillprofiles[i]
Each object in that array, has a number of properties and one of those properties is named skills so you would get that property with
skillprofiles[i].skills
The contents of the skills property is another array so you would get an item from that aray with this:
skillprofiles[i].skills[j]
That array holds objects with their own properties so you would access a specific property with this:
skillprofiles[i].skills[j].item_name

Categories