Ionic "track by" error with tinder cards - ionic-framework

I started learning Ionic 2 weeks ago and right now I am creating a small project to practice.You can download my project from my Github : https://github.com/KaanYildirim/ionicTest
I am trying to use tinder like cards which is created from the ionic team itself. (https://github.com/driftyco/ionic-ion-tinder-cards)
I have tried every possible solution with "track by" expression but I am still getting this error:
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: card in cards track by card.id, Duplicate key: undefined, Duplicate value: undefined
I have tried to fix this error with "track by $index" and "track by card.id "(every card has an "id" attribute in .Json file) but it didn't worked. I guess that i made a small mistake and can't find it.
Can someone please help me? Thanks
index.html:
<td-cards>
<td-card ng-repeat="card in cards track by card.id" on-destroy="cardDestroyed($index)" on-swipe="cardSwiped($index)">
<div class="list card myCard">
<!-- Card Header-->
<div class="item topicDescription cardHeader">
<p>{{card.topicDescription}}</p>
</div>
<!-- Card Body-->
<div class="item item-body noBorder">
<img class="full-image" src="{{card.image}}">
<h3 class="cardTitle">{{card.title}}</h3>
<p>{{card.summary}}</p>
</div>
<!-- Card Footer-->
<div class="item tabs tabs-secondary tabs-icon-left cardFooter">
<a class="tab-item" ng-click="readMore($index)" href="#">
<i class="{{card.actionButtonIcon}}"></i>
{{card.actionButtonText}} {{card.type}} ( {{card.additionalInfo}} )
</a>
<a class="tab-item" ng-click="share($index)" href="#">
<i class="icon ion-share"></i>
Share
</a>
</div>
</div>
</td-card>
</td-cards>
Json File:
{
"articles": [
{
"id":1,
"topicDescription": "Find a Idea",
"image": "img/uber.jpg",
"title": "Uber Lowers Fares In Over 100 Cities",
"summary": "Uber is lowering prices in over 100 U.S. and Canadian cities, effective tomorrow. January is a slower month for the car service and the company says it is reducing fares in order to increase demand.",
"link": "http://techcrunch.com/2016/01/08/uber-lowers-fares-in-over-100-cities/",
"actionButtonIcon": "icon ion-ios-glasses-outline",
"actionButtonText": "Read",
"type":"Article",
"additionalInfo": "3 min"
},
{
"id":2,
"topicDescription": "Test a Idea",
"image": "img/lean.jpg",
"title": "The Lean Startup",
"summary": "Great book about startups and how to validate your idea without spending to much money and time.",
"link": "http://www.amazon.de/Lean-Startup-Innovation-Successful-Businesses/dp/0670921602/ref=sr_1_2?ie=UTF8&qid=1452779528&sr=8-2&keywords=the+lean+startup",
"actionButtonIcon": "icon ion-ios-bookmarks-outline",
"actionButtonText": "Buy",
"type":"Book",
"additionalInfo": "Amazon"
},
{
"id":3,
"topicDescription": "Build",
"image": "img/evernote.jpg",
"title": "Note Taking App",
"summary": "From short lists to lengthy research, no matter what form your writing takes, Evernote keeps you focused on moving those ideas from inspiration to completion.",
"link": "https://evernote.com/?var=3",
"actionButtonIcon": "icon ion-hammer",
"actionButtonText": "Download",
"type":"App",
"additionalInfo": "App Store"
},
{
"id":4,
"topicDescription": "Measure",
"image": "img/steve.jpg",
"title": "Steve Blank: How to Build a Great Company",
"summary": "Join Silicon Valley serial entrepreneur-turned-educator Blank in a lively discussion with Dan'l Lewin of Microsoft. This program will introduce best practices, lessons and tips that have swept the startup world, offering a wealth of proven advice and information for entrepreneurs of all stripes.",
"link": "https://www.youtube.com/watch?v=1RTcXwJuCaU",
"actionButtonIcon": "icon ion-ios-videocam-outline",
"actionButtonText": "Watch",
"type":"Video",
"additionalInfo": "Youtube"
},
{
"id":5,
"topicDescription": "Find a Idea",
"image": "img/uber.jpg",
"title": "Uber Lowers Fares In Over 100 Cities",
"summary": "Uber is lowering prices in over 100 U.S. and Canadian cities, effective tomorrow. January is a slower month for the car service and the company says it is reducing fares in order to increase demand.",
"link": "http://techcrunch.com/2016/01/08/uber-lowers-fares-in-over-100-cities/",
"actionButtonIcon": "icon ion-ios-glasses-outline",
"actionButtonText": "Read",
"type":"Article",
"additionalInfo": "3 min"
},
{
"id":6,
"topicDescription": "Test a Idea",
"image": "img/lean.jpg",
"title": "The Lean Startup",
"summary": "Great book about startups and how to validate your idea without spending to much money and time.",
"link": "http://www.amazon.de/Lean-Startup-Innovation-Successful-Businesses/dp/0670921602/ref=sr_1_2?ie=UTF8&qid=1452779528&sr=8-2&keywords=the+lean+startup",
"actionButtonIcon": "icon ion-ios-bookmarks-outline",
"actionButtonText": "Buy",
"type":"Book",
"additionalInfo": "Amazon"
},
{
"id":7,
"topicDescription": "Build",
"image": "img/evernote.jpg",
"title": "Note Taking App",
"summary": "From short lists to lengthy research, no matter what form your writing takes, Evernote keeps you focused on moving those ideas from inspiration to completion.",
"link": "https://evernote.com/?var=3",
"actionButtonIcon": "icon ion-hammer",
"actionButtonText": "Download",
"type":"App",
"additionalInfo": "App Store"
},
{
"id":8,
"topicDescription": "Measure",
"image": "img/steve.jpg",
"title": "Steve Blank: How to Build a Great Company",
"summary": "Join Silicon Valley serial entrepreneur-turned-educator Blank in a lively discussion with Dan'l Lewin of Microsoft. This program will introduce best practices, lessons and tips that have swept the startup world, offering a wealth of proven advice and information for entrepreneurs of all stripes.",
"link": "https://www.youtube.com/watch?v=1RTcXwJuCaU",
"actionButtonIcon": "icon ion-ios-videocam-outline",
"actionButtonText": "Watch",
"type":"Video",
"additionalInfo": "Youtube"
}
]
}

I examined your code. In your controllers.js file you handle the cardSwiped event by manually adding an undefined card to your list
$scope.cardSwiped = function(index) {
var newCard = // new card data
$scope.cards.push(newCard);
};
This causes your cards to have multiple undefined elements that ng-repeat will be forced to handle as duplicates. Remove/fix that handler and things should work.
BTW, this code will work normally because javascript will handle them as a single line var newCard = $scope.cards.push(newCard); This means at the end of the function your newCard variable will have the new length of the cards array.

Related

Adding booking meta data to Google Search

I can't for the life of me figure out how this company adding this meta data to their Google search.
Does anyone know how to add the data and booking links like the below image?
Thanks
What you are seeing in these search results is what Google defines as "Rich Results" more information can be viewed in Google's Structured Data documentation. Specifically Edgewater Medical center is taking advantage of the event functionality to define times and dates.
This can be verified by pasting the page's source in the Rich Results Test tool, results for this page can be viewed at
https://search.google.com/test/rich-results?utm_campaign=devsite&utm_medium=jsonld&utm_source=event&id=m1ZrUywePCZ_NglFJIjZfg
According to google documentation in order to make this happen you have to follow a few steps:
Ensure that Googlebot can crawl your event pages (meaning, your pages
aren't protected by a robots.txt file or robots meta tag).
Ensure that your server can handle increased crawl rate.
Make sure you follow the Google guidelines.
Add structured data to your event pages. Currently, the event experience on Google only supports pages that focus on a single event. We recommend focusing on adding markup to your event posting pages instead of pages that list schedules or multiple events.
An example of such "structured data" for a standard event is shown below:
<html>
<head>
<title>The Adventures of Kira and Morrison</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Event",
"name": "The Adventures of Kira and Morrison",
"startDate": "2025-07-21T19:00-05:00",
"endDate": "2025-07-21T23:00-05:00",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"eventStatus": "https://schema.org/EventScheduled",
"location": {
"#type": "Place",
"name": "Snickerpark Stadium",
"address": {
"#type": "PostalAddress",
"streetAddress": "100 West Snickerpark Dr",
"addressLocality": "Snickertown",
"postalCode": "19019",
"addressRegion": "PA",
"addressCountry": "US"
}
},
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
"offers": {
"#type": "Offer",
"url": "https://www.example.com/event_offer/12345_201803180430",
"price": "30",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2024-05-21T12:00"
},
"performer": {
"#type": "PerformingGroup",
"name": "Kira and Morrison"
},
"organizer": {
"#type": "Organization",
"name": "Kira and Morrison Music",
"url": "https://kiraandmorrisonmusic.com"
}
}
</script>
</head>
<body>
</body>
</html>

schema.org structure for more than one ebook

I want sell more than one ebook on my site. But all ebooks are in one package for a specific price. I dont know, how i must setup the schema.org. My first creation look like this:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"mainEntity":{
"#type": "Book",
"author": "www.example.com",
"bookFormat": "https://schema.org/EBook",
"fileFormat": "application/pdf"
"image": "example.jpg",
"inLanguage": "English",
"name": "Example",
"numberOfPages": "20",
"genre": "Example",
"description": "Description example",
"keywords": "Keyword example",
"offers": {
"#type": "Offer",
"price": "1.00",
"priceCurrency": "USD",
"category": "",
"availability": "https://schema.org/OnlineOnly",
"availableDeliveryMethod": "http://purl.org/goodrelations/v1#DeliveryModeDirectDownload"
},
"publisher": "www.example.com",
}
}
</script>
Thanks for your help!
Your product seems a grouped product of downloadable products, which are enlisted eBooks.
There are two ways to implement a list format for your structured data:
Summary page + multiple full details pages
A single, all-in-one-page list
If the page has full details of each eBook in the list prefer A single, all-in-one-page list else if the page has short description of each eBook in the list use Summary page + multiple full details pages as described in here.
Regards,
Vivek

Confused about how #id in structured data works

Basically, I'm trying to add BlogPosting, TechArticle and WebPage structured data types to my posts, but I'm getting errors in Google's structured data testing tool. They seem to be centred around when I link back to an Organization structured data type I've defined on my homepage, to save me having to repeat the same code across multiple pages.
Here's the structured data testing tool instance. Can anybody explain how I can properly link to the Organization data type (which is sitting on my homepage) in the author, creator and publisher properties?
https://search.google.com/structured-data/testing-tool#url=https%3A%2F%2Fwww.lukeharrison.dev%2Farticles%2Fmike-brewer-motors-wins-best-online-experience-at-autotraders-2018-retailer-awards%2F
I feel as though it may be down to me not fully understanding the #id property, and how to properly can use it to link structured data together to reduce repetitive data.
Here's the code involved:
The BlogPosting
The linked Organisation
The errors I'm receiving
Example of BlogPosting
{
"#context": "http://schema.org",
"#type": "BlogPosting",
"about": "Great news! Mike Brewer Motors - a project I've been heavily involved in over the past few years - has won the 'Best Online Experience' at the Autotrader 2018 Retailer Awards.",
"articleSection": "Blog Posts",
"author": {
"id": "https://www.lukeharrison.dev#organization"
},
"copyrightHolder": {
"id": "https://www.lukeharrison.dev#person"
},
"copyrightYear": "2019",
"creator": {
"id": "https://www.lukeharrison.dev#organization"
},
"dateCreated": "2018-07-20",
"dateModified": "2018-07-20",
"datePublished": "2018-07-20",
"description": "Great news! Mike Brewer Motors - a project I've been heavily involved in over the past few years - has won the 'Best Online Experience' at the Autotrader 2018 Retailer Awards.",
"genre": "Web Design & Front-End Development",
"headline": "Mike Brewer Motors wins 'Best Online Experience' at Autotrader's 2018 Retailer Awards - Luke Harrison",
"image": {
"#type": "ImageObject",
"height": 512,
"url": "https://s.gravatar.com/avatar/c34b34964896ad0552a5b342ae08c1e2?s=512",
"width": 512
},
"inLanguage": "en-GB",
"isFamilyFriendly": "true",
"keywords": [
"news"
],
"mainEntityOfPage": "https://www.lukeharrison.dev/articles/mike-brewer-motors-wins-best-online-experience-at-autotraders-2018-retailer-awards",
"publisher": {
"id": "https://www.lukeharrison.dev#organization"
}
}
Example linked Organization, which sits on another page
{
"#context": "http://schema.org",
"#id": "https://www.lukeharrison.dev#organization",
"#type": "Organization",
"additionalType": [
"http://www.productontology.org/id/Web_design",
"http://www.productontology.org/doc/Search_engine_optimization",
"http://www.productontology.org/doc/Web_development"
],
"foundingDate": "2013",
"legalName": "Luke Harrison - UX / Web Developer",
"logo": "https://www.lukeharrison.dev/img/share-26bfb69f23.png",
"name": "Luke Harrison - UX / Web Developer",
"sameAs": [
"https://twitter.com/webdevluke?lang=en-gb",
"https://www.linkedin.com/in/lukedidit/",
"https://github.com/WebDevLuke",
"https://codepen.io/lukedidit/"
],
"url": "https://www.lukeharrison.dev"
}
The errors I'm receiving in my BlogPosting structure
author, creator and publisher:
The attribute publisher.itemtype has an invalid value.
A value for the name field is required.
The errors are about Google’s Article rich result (if you don’t want to get this rich result, you can ignore these errors).
For AMP pages, author and publisher are required properties. They require actual items as value, #id references are not supported. You can still provide the #id, but you need to specify the #type and the required properties in addition.

Fix SDTT warning on JobPosting: "The value field is recommended."

On the Google Structured Data Testing Tool I get a warning for not entering a value in the baseSalary property.
The value field is recommended. Please provide a value if available.
However, I have added a value.
{
"#context": "http://schema.org",
"#type": "JobPosting",
"hiringOrganization": "Google",
"validThrough": "2018-12-31T00:00",
"baseSalary": {
"#type": "MonetaryAmount",
"currency": "USD",
"value": {
"#type": "QuantitativeValue",
"minValue": 40.00,
"maxValue": 50.00,
"unitText": "HOUR"
}
},
"jobBenefits": "Medical, Life, Dental",
"datePosted": "2011-10-31",
"description": "Description: ABC Company Inc. seeks a full-time mid-level software engineer to develop in-house tools.",
"educationRequirements": "Bachelor's Degree in Computer Science, Information Systems or related fields of study.",
"employmentType": "Full-time",
"experienceRequirements": "Minumum 3 years experience as a software engineer",
"incentiveCompensation": "Performance-based annual bonus plan, project-completion bonuses",
"industry": "Computer Software",
"jobLocation": {
"#type": "Place",
"address": {
"#type": "PostalAddress",
"addressLocality": "Poole",
"addressRegion": "Dorset",
"streetAddress": "33 Holton Road",
"postalCode": "BH16 6LT"
}
},
"occupationalCategory": "15-1132.00 Software Developers, Application",
"qualifications": "Ability to work in a team environment with members of varying skill levels. Highly motivated. Learns quickly.",
"responsibilities": "Design and write specifications for tools for in-house customers Build tools according to specifications",
"salaryCurrency": "USD",
"skills": "Web application development using Java/J2EE Web application development using Python or familiarity with dynamic programming languages",
"specialCommitments": "VeteranCommit",
"title": "Software Engineer",
"workHours": "40 hours per week"
}
Could someone please provide a fix so the code passes the Google Structured Data Testing Tool?
Your code violates the standard:
baseSalary doesn't contain something like hours, but only currency and the value or range.
Beside of this there is a inconsistency:
you write on one place:
"minValue": 40.00,
"maxValue": 50.00,
"unitText": "HOUR"
On another place:
"workHours": "40 hours per week"
What now? 40 hours or between 40 and 50?
Another thing: workHours are not for amount of working hours per week, but for typical beginning and ending of shift.

Is the Event type suitable for running races?

I have inline Schema.org code via itemprop attributes, on all event pages on a website.
Search Console is flagging up recommendations that I use performer and various other properties, however due to the nature of the events (they are races), there are no performers.
Does this imply that event is the wrong type of Schema.org here, or can the warnings be safely ignored?
The tags used are:
type
image
name
location
type
address
type
streetaddress
addresslocality
address country
type
name
aggregaterating
type
reviewcount
ratingvalue
The Event type is perfectly suitable for races. But you should use the more specific SportsEvent.
Schema.org never requires any property, but consumers (who offer features based on Schema.org structured data) have their own requirements. If you want to get the feature, you would have to comply; if you don’t want the feature (or you can’t get it because you can’t provide all the required data), you can simply ignore any kind of errors/warnings from this consumer.
The consumer Google Search offers the event rich result feature, which has required and recommended properties. The performer property is just recommended, so it should be possible to get the event rich result without providing a performer.
Note that the guide of Google for Event requires the use of the following property that are not in the markup scheme you specified: startDate.
There are also many recommended properties out there that you are missing and these lower the value of the rich results of Google in the SERP:
description
endDate
location.name
offers
Note that the property executor can have the embedded type PerformingGroup, e.g.:
"performer": {
"#type": "PerformingGroup",
"name": "McLaren"
}
This way you can create markup for the team but not for each rider.
More detailed markup with structured data enriches the SERP of your web pages.
Beeing a webdeveloper and racedirector, I have been looking into this for some time now. If you take a look at the races website (no, this is no advertising for the best race on the planet), you can see that I have an event (SportsEvent) and six different competitions on that very day: 100km ultramarathon
What you see here is what I assembled so far to make my race as machine readable as possible. I have the adress, the different competitions, the place, the entry fees and the offers, the dooring time and all the stuff I might need google to know.
The only thing that is missing is the list of the competitors, the runners of each race. I am doing research about how to do this right now, but "sports" in microformats seems to be a team based thing. If I found out how to do it right, I'll post an update here. And you'll see it in the websites source code of course.
I have copied the LD-JSON here for future reference in case I'd edit the code of the website.
FYI: I am getting the participants data as XML feed directly from the raceresult registration website.
<script type='application/ld+json'>
{
"#context": "http://schema.org",
"#type": "SportsEvent",
"#id": "https://whew100.de/wettbewerbe/whew100.html",
"name": "WHEW100 Ultramarathon",
"image": "https://whew100.de/assets/images/WHEW100_transparent.png",
"url": "https://whew100.de/wettbewerbe/whew100.html",
"description": "WHEW100 Ultramarathon in Wuppertal über Wülfrath, Velbert, Heiligenhaus, Essen, Hattingen und Sprockhövel. Auf alten Bahntrassen zwischen Wuppert und Ruhr.",
"startDate": "2019-05-04T07:00:00",
"endDate": "2019-05-04T22:00:00",
"doorTime": "2019-05-04T06:00:00",
"maximumAttendeeCapacity": "200",
"aggregateRating": {
"#type": "AggregateRating",
"ratingValue": "4.9",
"reviewCount": "84"
},
"location": {
"#type": "Place",
"name": "Utopiastadt",
"sameAs": "https://www.clownfisch.eu/utopia-stadt/bahnhof-mirke/",
"address": {
"#type": "PostalAddress",
"streetAddress": "Mirker Straße 48",
"addressLocality": "Wuppertal",
"postalCode": "42105",
"addressCountry": "Germany"
}
},
"competitor": [
],
"offers": {
"#type": "Offer",
"description": "Anmeldung zum WHEW100",
"url": "http://my.raceresult.com/105067/",
"price": "75",
"priceCurrency": "EUR",
"availability": "200",
"validFrom": "2018-09-01T00:00:00"
},
"superEvent": {
"#id": "https://whew100.de",
"name": "WHEW100",
"startDate": "2019-05-04T07:00:00",
"endDate": "2019-05-04T22:00:00",
"location": {
"#type": "Place",
"name": "Utopiastadt",
"sameAs": "https://www.clownfisch.eu/utopia-stadt/bahnhof-mirke/",
"address": {
"#type": "PostalAddress",
"streetAddress": "Mirker Straße 48",
"addressLocality": "Wuppertal",
"postalCode": "42105",
"addressCountry": "Germany"
}
}
}
}
</script>