In my laravel controller I wrote:
public function index()
{
$products = Product::all(); // get all products
$products['page_title'] = 'Demo Products'; // page title
return response()->json($products);
}
And in Angular 4, I wrote for this:
constructor(private productService: ProductService, private title: Title) { }
ngOnInit() {
//console.log('data');
this.productService.getProducts()
.subscribe(data => {
this.products = data;
this.title.setTitle(data.page_title);
},
And in the html under the angular I wrote the following:
<article class="col-md-4" *ngFor="let product of products">
<div class="font-weight-bold">{{product.product_name}}</div>
<p>{{product.description}}</p>
<p>{{product.rating}}</p>
</article>
In index.html, I wrote <title></title>
It shows the console error as below:
ProductComponent.html:7 ERROR Error: Error trying to diff '[object
Object]'. Only arrays and iterables are allowed
In postman, I see the following:
"18": {
"id": 19,
"product_name": "Adam Walsh",
"description": "Rabbit coming to look for her, and the small ones choked and had just upset the week before. 'Oh, I BEG your pardon!' cried Alice in a shrill, loud voice, and see after some executions I have to ask.",
"rating": 0,
"price": 59.2,
"created_at": "2018-03-22 11:04:39",
"updated_at": "2018-03-22 11:04:39"
},
"19": {
"id": 20,
"product_name": "Marilyne Kulas II",
"description": "I want to stay in here any longer!' She waited for a minute or two sobs choked his voice. 'Same as if his heart would break. She pitied him deeply. 'What is it?' he said, turning to Alice an.",
"rating": 5,
"price": 13.5,
"created_at": "2018-03-22 11:04:39",
"updated_at": "2018-03-22 11:04:39"
},
"page_title": "Demo Products"
}
The error is sent because *ngFor requires an array to iterate.
Assigning $products['page_title'] as if $products was an associative array is wrong. $products is a Illuminate\Database\Eloquent\Collection. When sending it as json, Laravel parse it as an indexed array. But i guess you broke it by assigning 'page_title' this way.
Try to print_r($products) before sendind it, to check that.
I'd rather do something like this :
return response()->json(['data' => $products, 'page_title' => 'Demo Products']);
And in angular :
this.productService.getProducts()
.subscribe(response => {
this.products = response.data;
this.title.setTitle(response.page_title);
},
Related
There is some list of elements in json format, it looks like this:
[{
'id': 0,
"name": "Category name1",
"services": [{
"id": 0,
"name": "Product name1"
}, {
"id": 1,
"name": "Product name2"
}]
},
{
'id': 1,
'name': "Category name2",
"services": [{
"id": 0,
"name": "Product name1"
}, {
"id": 1,
"name": "Product name2"
}]
}
]
I'm trying to get only the entire "services" array from the first category. Conditionally, I'm trying to get it as follows:
this.class = this.http.get('/assets/products.json');
this.class.forEach(element => {
if (element.id == ID) //The ID is obtained when calling the function in which this code is executed
{
console.log(element.services);
}
}
However, this gives me absolutely nothing and "undefined" is output to the console, however, with the same array and under the same conditions on the site https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach it (foreach and console.log) outputs everything I need.
//The same foreach only on the mozilla website
array1.forEach(item => {
if(item.id==1){ //1 вместо ID
console.log(item.services);
}});
Output to the console: Array [Object { id: 0, name: "Product name1"}, Object { id: 1, name: "Product name2"}].
P.S. I don't really need this list of products in the console, I'm trying to pass a variable, but since undefined is passed to the variable, as well as to the console, I can't use the variable and call it to display products on the page. All this is used in the typescript angular project.
The HttpClient methods like get return observables, to which you need to subscribe to in order for the request to even get executed. In your situation, the class property is only holding a reference to the observable returned by calling this.http.get. Try subscribing to the observable and use the result to extract the data that you need.
this.http.get<any[]>('/assets/products.json').subscribe((data) => {
this.class = data;
this.class.forEach((element) => {
if (element.id == ID) {
console.log(element.services);
}
});
});
I'm quite new in AngularJs and I'm trying to get data from 2 different JSON returning services.
I have a list, obtained from one service, where I'm showing the user ID.
This is working, but what I need is, given that user ID, obtain the user's first name and last name from the other JSON.
How can I do it? Any help is welcome.
This is the AngularJs (1.6) controller:
controller('myReservations',function($scope,$http){
$scope.reserve = [];
$scope.sId = s;
$http.get('/reserve/').then(
function(response){
$scope.reserve = response.data.description;
},
function(response){
console.log(response.statusText);
}
);
})
And the HTML:
<ul class="reservationsList" ng-controller="myReservations">
<li ng-repeat="res in reserve | filter: {ideventroom: sId}">
User: {{res.iduser}} <br>
First name: <!-- Here goes the first name --><br>
Last name: <!-- Here goes the last name -->
</li>
</ul>
And the services are returning the following JSON.
In "/reserve/" I get:
{
"status": 0,
"description": [
{
"id": 1,
"ideventroom": 3,
"iduser": 2
},
{
"id": 2,
"ideventroom": 3,
"iduser": 1
}
]
}
In "/user/2" I get:
{
"status": 0,
"description": [
{
"id": 2,
"firstname": "John",
"lastname": "Smith",
"email": "johnny#smithy.co",
"phone": "11111111"
}
]
}
Thank you!
You can chain a second then function onto your first one. Inside that function, you can make your other http request using your now available userid.
I want to loop through an array of objects in angular 4 , I use a .ts file to export array as a variable in posts.ts
export var posts = [
{
"name":"art",
"title":"Art",
"items":[
{
"id": "1",
"title":"Tooling Up",
"author":"Amber Bravo",
"date":"June 14 2015",
"primaryColor":"#5a7785",
"secondaryColor":"#455a64",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/tooling-up-header-a13cfd9a.svg",
"desc":"How a new generation of prototyping tools at Google will help designers build better software.",
"content":"# content goes here"
},
{
"id": "2",
"title":"Expressing Brand in Material",
"author":"Viktor Persson & Rachel Been",
"date":"July 4 2015",
"primaryColor":"#202226",
"secondaryColor":"#333",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/article_brand_2x1_202226-fc539618.svg",
"desc":"Material design offers a system for designing functional and elegant software. How does your brand fit into the framework? We’ve created a step-by-step guide to staying on-brand while going material.",
"content":"# content goes here"
},
{
"id": "3",
"title":"New Design Tools",
"author":"Amber Bravo",
"date":"July 29 2015",
"primaryColor":"#3e50b4",
"secondaryColor":"#303fc3",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/150727_GD_Article_ToolingUpFurther_1x1Tile-01-86c8e03e.svg",
"desc":"See Also: (More) thoughts on design tools",
"content":"# content goes here"
}
]
},
{
"name":"film",
"title":"Film",
"items":[
{
"id": "1",
"title":"Design from iOS to Android (and Back Again)",
"author":"Roman Nurik & Viltor Persson",
"date":"Aug 20 2015",
"primaryColor":"#3e50b4",
"secondaryColor":"#303F9F",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/renditions/Article_iOS_to_Android_Header_3e50b4-f064882f-1240.png",
"desc":"A practical guide to designing across platforms",
"content":"# content goes here"
},
{
"id": "2",
"title":"Demystifying Density",
"author":"Sebastien Gabriel",
"date":"July 10 2015",
"primaryColor":"#00ccb8",
"secondaryColor":"#00b7a5",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/article_dpi_00ccb8-34fdd39e.svg",
"desc":"Sebastien Gabriel takes one for the team with his exhaustive guide to DPI & PPI",
"content":"# content goes here"
},
{
"id": "3",
"title":"Pixate and Form 1.3",
"author":"Google Design",
"date":"May 30 2015",
"primaryColor":"#eeeeee",
"secondaryColor":"#9e9e9e",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/pixate-and-form-1-3-header-2061f19f.svg",
"desc":"Discover the latest features and start designing native prototypes on your device.",
"content":"# content goes here"
},
{
"id": "4",
"title":"Welcome to the New Google Design",
"author":"Google Design",
"date":"Sep 10 2015",
"primaryColor":"#3367d6",
"secondaryColor":"#2755CC",
"image":"https://g-design.storage.googleapis.com/production/v5/assets/Article_Welcome_Header_2880-ce3ec22d.svg",
"desc":"More design, all the time",
"content":" # content goes here"
}
]
},
{
"name":"photography",
"title":"Photography",
"items":[]
},
{
"name":"design",
"title":"Design",
"items":[]
},
{
"name":"topten",
"title":"Top Ten",
"items":[]
},
{
"name":"aday",
"title":"A Day in the Life",
"items":[]
}
]
then I import it in app.componenet.ts normally with :
import { posts } from './posts';
now what I don't know is how to loop through it or how to load json file then loop through it I mean how to loop in html to display data inside the app.componenet.html
You have to pass this array to view.
#Component(...)
class AppComponent {
posts = posts;
...
And then in view you have to use *ngFor directive.
<ng-container *ngFor="let post of posts">
{{ post.title }}
</ng-container>
An (edited for readability) version of my json looks like this.
It's actually the reddit front page in json form:
{
"kind": "Listing",
"data": {
"modhash": "fb7jljbeer6a0dbec0b7b939c890078b5a92d221b3e2b31cec",
"children": [
{
"kind": "t3",
"data": {
"subreddit": "gifs",
"id": "66wssv",
"author": "GuacamoleFanatic",
"name": "t3_66wssv",
"subreddit_name_prefixed": "r/gifs",
"domain": "gfycat.com",
"thumbnail": "https://b.thumbs.redditmedia.com/E4FB3khTGQ_D8KP-P7KEVXpB9MzY_XDWUhtPmGnNOuE.jpg",
"subreddit_id": "t5_2qt55",
"permalink": "/r/gifs/comments/66wssv/8_year_old_tillys_first_couple_of_seconds_wearing/",
"url": "https://gfycat.com/VacantRequiredAmethystinepython",
"title": "8 year old Tilly's first couple of seconds wearing a bionic hand.",
"created_utc": 1492877987,
"num_comments": 504,
}
},
{
"kind": "t3",
"data": {
"subreddit": "IAmA",
"id": "66wut7",
"author": "JoergS",
"name": "t3_66wut7",
"subreddit_name_prefixed": "r/IAmA",
"domain": "self.IAmA",
"thumbnail": "self",
"subreddit_id": "t5_2qzb6",
"permalink": "/r/IAmA/comments/66wut7/iama_jörg_sprave_the_bald_crazy_german_who_runs/",
"url": "https://www.reddit.com/r/IAmA/comments/66wut7/iama_jörg_sprave_the_bald_crazy_german_who_runs/",
"title": "IamA (Jörg Sprave, the bald crazy German who runs \"The Slingshot Channel\" on YouTube.) AMA!",
"created_utc": 1492878607,
"num_comments": 781,
}
},
The controller is very simple:
angular.module('redditdupe').controller('frontPage', ['$scope', '$http', '$routeParams',
function frontPage($scope, $http){
$http({
method: 'GET',
url: 'https://www.reddit.com/.json'
})
.
then(
function successCallback(response)
{
$scope.children=response.data.data.children;
}
,
function errorCallback(response) {
}
);
}]);
And so is the html:
<div class="cartouche" ng-repeat="child in children">
<div ng-repeat="data in child">
<img src="{{ data.thumbnail }}"><br>
{{ data.title }} ({{ data.domain }})<br>
{{ data.created_utc * 1000 | date:'yyyy-MM-dd HH:mm:ss Z' }} {{data.author}} {{ data.subreddit_name_prefixed }}<br>
{{ data.num_comments }}<br>
</div>
</div>
However, ng-repeat shows
a blank set of results, followed by
a real set of results,
followed by another blank set,
followed by another real set
... and so on
Like this:
<--- blank line
() <--- probably the domain gfycat.com, except it's blank
null < --- dunno
<--- probably the comment count, but is blank line
8 year old Tilly's first couple of seconds wearing a bionic hand. (gfycat.com)
2017-04-22 09:19:47 -0700 GuacamoleFanatic r/gifs
1959
() <--- then the same shenanigans again
null
Seen at the March for Science (i.redd.it)
2017-04-22 09:45:18 -0700 Polymathyx r/pics
338
I've googled a lot and this doesn't seem to fit the "consumption cycle" explanation because it's not that the entire collection is displayed in sequence once, and then twice.
This is each element being cycled twice individually, first blank then filled out.
I've been slamming my head against the desk for days.
What is the cause and, more importantly, what is the solution please?
Very grateful for any suggestions.
I am running into an issue when my Model is fetched from the server. I see the correct JSON returned back from the server in chrome dev tools but the model does not update with the returned values.
var listtemplate = new ListTemplateModel.Model({id: id});
listtemplate.fetch();
I see the correct data in Chrome dev tools at this point. Here is what comes back from the server:
{
"title": "Template one",
"id": "template_one",
"steps": [
{
"description": "I love it",
"id": 1,
"created_at": "2012-12-24T18:01:48.402Z"
},
{
"description": "This is rubbish!",
"id": 1,
"created_at": "2012-12-24T18:01:48.402Z"
}
],
"created_at": "2012-12-24T18:01:48.402Z"
}
but console logging the JSON show me just the default value and the id that was passed in during the model creation.
console.log(listtemplate.toJSON());
and this returns:
{id: "template_one", title: "", steps: Array[0]}
My model looks like this (I am using Require.js, hence the Model has been renamed to ListTemplateModel above)
var Model = B.Model.extend({
defaults: {
title: '',
id: 0,
steps: []
},
urlRoot: 'xxx'
});
Any ideas?
Edit
#Amulya's answer set me on the right track and then i discovered "then". Hope this helps someone running into the same issue:
listtemplate.fetch().then(function(){
//update the view
});
The reason maybe because you do not wait for the fetch to be completed. Try this:
var listtemplate = new ListTemplateModel.Model({id: id});
listtemplate.fetch({
success: function() {
// fetch successfully completed
console.log(listtemplate.toJSON());
},
error: function() {
console.log('Failed to fetch!');
}
});