How to retrieve nested json object data with Ionic - angularjs

I am working with the api from The Movie Database. In my Ionic project I was able to make a http request to pull in some data for a movie. However the json object is a nested json object, so I am having some trouble trying to access the genres of a movie:
For the purpose of this question I will display 1 nested json object:
I want to show the information like so -> Genre: Action - Comedy - Drama
My code for the controller is the following:
$scope.init = function(){
MovieService.getMovieById($stateParams.id).then(function(data){
$scope.trending_movie = data;
console.log($scope.trending_movie);
$scope.genres = data.genres;
console.log($scope.genres);
});
}
If I do this bit of code:
$scope.genres = data.genres;
It just returns met the json object of the genres like so:
The thing is now that I am able to read out the genres but because I access the data with a ng-repeat it will show like this:
How to get the genres on 1 line without having to repeat the word "Genre"?
Here is my html code:
<div ng-repeat="genre in genres">
<p class="movie-info-p">Genre: {{genre.name}}</p>
</div>

you should get "Genre:" out of your ng-repeat and if you want your genres to be in the same line, you shouldn't put them in tag.
There is this solution:
<div> Genre:
<div ng-repeat="genre in genres">
<span class="movie-info-p">{{genre.name}}</span>
</div>
</div>
Another solution is to generate this string in the controller with a for loop and send it to the view

Related

Vue.js array is mixed up after reloading data

The data in the Vue.js array with JSON objects in it is mixed up after reloading them from Spring backend.
I am trying to make a frontend with Vue.js for editing the data on the Spring backend. Vue.js makes a call to the backend with axios, it returns a list of items that is rendered on the page with a v-for. The items can be edited separately, when the 'Save' button is clicked for an item, the item is sent to the backend and the data is updated in the database. After this, when I hit reload in the browser (or close and open the same page) the data is reloaded from the server but its mixed up.
loadExercises(){
axios({url:'http://localhost:5000/exercises/all'}).then(resp => {
this.exercises = resp.data;
})
}
This is the function that loads the data.
This is the array originally : https://imgur.com/5x8TiwY
This is the array after reload, I edited the first entry: https://imgur.com/d6G4SMm
The backend returns the correct objects, the only difference is the that
the entry which was edited is the last in the array (and it was the first in the example case before the edit). The id-s do not change during saving, just the details are updated, like name or description.
This is the part of the template that generates the html, just in case it is because something in there.
<div role="tablist" id="container" v-bind:key="ex.id" v-for="ex in exercises">
<b-card no-body class="mb-1 customcard">
<b-card-header header-tag="header" class="p-1 alignleft" role="tab" v-b-toggle="`accordion${ex.id}`">
<span>{{ex.name}}</span>
</b-card-header>
<b-collapse v-bind:id="`accordion${ex.id}`" accordion="my-accordion" role="tabpanel">
<b-card-body class = "alignleft">
<p class="card-text">
Name: <b-form-input
v-bind:value="`${ex.name}`"
v-bind:id="`input${ex.id}`"
v-on:input="saveExName(ex.id)"></b-form-input>
Target: {{ex.target}} <b-form-select v-on:input="onTargetChange(ex.id)"
v-bind:id="`target${ex.id}`" >
<option v-bind:key = "target" v-for="target in targets" :value="target" >{{target}}</option>
</b-form-select>
Description: <b-form-textarea
v-bind:value="`${ex.description}`"
:rows="3"
:max-rows="6"
v-on:input="saveExDesc(ex.id)"
v-bind:id="`textarea${ex.id}`"></b-form-textarea>
</p>
<div class="alignright">
<b-button v-on:click="saveExUpdate(ex.id)">Save</b-button>
</div>
</b-card-body>
</b-collapse>
</b-card>
</div>
Any ideas why this is happening?

Filtering MongoDB data on the front end

I have little problems with MongoDb. I have 2 collections: Auctions and Users. In the "Users" i store obviously the users (mail, name...etc) In the Auctions i store products (creationdate, createdBy, FollowedBy, Invitations, image). Now, i want to show in every user's dashboard, only the products that he follows (his name is stored in the ""FOllowedBy" when he clicks on the botton Follow). If I have to filter on the backend, all it's clear, instead i want to load all the data from the DB and then filter that on the front end with angularJs.
With a simple field like createdBy it's easy: If i Have an user called "Alex"(for example) i can show the data only if createdBy match with Alex (or every other user). But the same thing doesn't work with an array field like "FollowedBy". If in the product "Table" createdby: "Mark", FollowedBy: "Alex" and "Jack", i can easy filter all the product to show only Mark's product, but i don't understand how to show only the products followed by Alex, cause this field is an array.
This is my back-end route.
app.get('/api/dashboard', function (req, res) {
AllAuctions
.find({}, function (err, auctions) {
if (err)
res.send(err);
console.log(auctions);
res.send(auctions);
});
});
I load it with $http with angularJs:
$http.get('/api/dashboard').then(function (AllAuctions) {
$scope.allauctions = AllAuctions.data;
});
If i have to filter the field "createdBy" i can do something like this:
<div class="panel panel-default" >
<div class="panel-heading">My Auctions</div>
<div class="panel-body">
<ul class="list-group" ng-repeat="allauction in allauctions">
<li class="list-group-item" ng-show="allauction.createdBy=='Alex'">
<img ng-src="{{allauction.imgUrl}}">
<div class="title"> {{allauction.title}} </div>
</li>
</ul>
</div>
</div>
But i don't understand how to filter a field like this:
FollowedBy: [
Shelly.name,
Dario.name
]
to show only the products followed by Dario.
If you want to do it in html you can do something like
ng-show="allauction.FollowedBy.indexOf('Alex')>=0"
However when you have multiple filters it will quickly become hardcore. You should define a filtering function in javascript that will compute a filtered array on which you can do a simple ng-repeat. Or you could alternatively add a flag to your allauction objects and perform ng-if/ng-show based on this flag. For exemple:
function updateFilteredData()
{
$scope.filteredData = [];
for(var i = 0; i< $scope.allauction; i++)
{
var auction = $scope.allauction[i];
if(auction.createdBy !== currentUser.name) //I assume currentUser is json object for your Alex user
continue;
if($scope.followByFilter && auction.FollowedBy.indexOf($scope.followByFilter) < 0)
continue; //I assume followByFilter is a string containing the name of a follower you are trying to filter
$scope.filteredData.push(auction);
}
}
You need to call this function once in $http get and each time filtering conditions change (ex: followByFilter name changes...).
Ofcorse you should ng-repeat on filteredData array instead of allauction.

How can I change a value inside of ng-repeat after the repeat complete?

I have a JSON which provides me a user's working experiences info. But country and city's are provided in a code format (TR,DE etc.)
I am using ng-repeat to pass them into html like this
<div ng-repeat="e in experiences">
<span>{{e.Name}}</span>
<span ng-init="changeCodeToFullName(e.Country)">{{vm.CountryFullName[$index]}}</span>
</div>
I am using ng-init to convert Country Code to full name. changeCodeToFullName is an angular service written by me, Is this a correct method? If it is, I can't access the dom to change CountryFullName value. I tried to access them in JS file like vm.CountryFullName[0]="TEST" but it didn't worked. I need to use e.Country variable after, therefore I can't change the original .e.Country value.
How can I access a variable inside of ng-repeat after ng-repeat completed?
How about using a custom filter:
<div ng-repeat="e in experiences">
<span>{{e.Name}}</span>
<span>{{e.Country | changeCodeToFullName}}</span>
</div>
angular.module('App').filter('changeCodeToFullName', function(YourService) {
return function(country) {
return YourService.getFullCountryName(country)
}
})
Here's an example: http://codepen.io/rustydev/pen/YWyqJB
This is one way of doing it - but this ngInit value won't be reparsed if the list updates. Why not just format the data in the JSON request response - such as:
$http.get("json.json").success(function(data) {
$scope.exeriences = data.map(function(obj) {
//Format results;
if (obj.Country == "DE") {
obj.Country = "Germany"; //etc
}
return obj;
});
});

What am I missing in rendering JSON object - AngularJS

In this Plunker why am I not able to access
{{ cartItem.selectedSeller.registered_name }}
Code
<div ng-repeat="cartItem in cartItems track by $index">
{{ cartItem.selectedSeller }} // I can access this
<h2> Registered Seller Name:</h2>
{{ cartItem.selectedSeller.registered_name }} // but not this
===============================
</div>
from what I know we put [] in case of an array else we can access object attributes using . . I am surely missing some tiny logic here. I want to show Seller name for each cart products.
Your json has an invalid format. Try check it here
"selectedSeller":"{\"registered_name\": \"6bc0317c-0b8b-4b39-96d4-c3377e64acfd_seller\", \"rating\": 1, \"id\": 64, \"delivers_to\": \"[{\\\"city_name\\\": \\\"Pune\\\", \\\"country\\\": \\\"India\\\", \\\"pin_code\\\": \\\"411057\\\"},{\\\"city_name\\\": \\\"Kolkata\\\", \\\"country\\\": \\\"India\\\", \\\"pin_code\\\": \\\"411058\\\"},{\\\"city_name\\\": \\\"Delhi\\\", \\\"cou
by the key selectedSeller you access string but not a object, where presented register_name property
Also, it is a good idea to use json filter, but it depends what version angular you are using.
{{ foo | json }}
Here I can see an advise about parse json, it resolve your problem, also, but I am not recommend for you that way, keep a json backend data in a consistent format and not remap it on the client side through the parsers or some custom methods.
cartItem.selectedSeller is a string, simply parse the string as a JSON like so in your controller:
$scope.cartItems = [];
$http({
method: 'GET',
url: 'data.json'
}).success(function(data) {
data.forEach(function(a){
a.selectedSeller = JSON.parse(a.selectedSeller);
$scope.cartItems.push(a);
});
});

ng-repeat doesn't seem to be working

I am trying to pull all items from my array called 'collections'. When I input the call in my html I see only the complete code for the first item in the array on my page. I am trying to only pull in the 'edm.preview' which is the image of the item. I am using Angular Firebase and an api called Europeana. My app allows the user to search and pick which images they like and save them to that specific user.
here is the js:
$scope.users = fbutil.syncArray('users');
$scope.users.currentUser.collections = fbutil.syncArray('collections');
$scope.addSomething = function (something) {
var ref = fbutil.ref('users');
ref.child($rootScope.currentUser.uid).child('collections').push(something);
}
$scope.addSomething = function(item) {
if( newColItem ) {
// push a message to the end of the array
$scope.collections.$add(newColItem)
// display any errors
.catch(alert);
}
};
and the html:
<ul id="collections" ng-repeat="item in collections">
<li ng-repeat="item in collections">{{item.edmPreview}}</li>
</ul>
First, remove the outer ng-repeat. You want to only add the ng-repeat directive to the element which is being repeated, in this case <li>.
Second, from your AngularJS code, it looks like you want to loop over users.currentUser.collections and not just collections:
<ul id="collections">
<li ng-repeat="item in users.currentUser.collections">{{item.edmPreview}}</li>
</ul>
And third, you're defining the function $scope.addSomething twice in your JavaScript code. Right now, the second function definition (which, incidentally, should be changed to update $scope.users.currentUser.collections as well) will completely replace the first.

Resources