Angular JS: Http:get on JSON created by local API - javascript

So I'm teaching myself Angular.js. Following a tutorial I found online, I created a RESTful API with Laravel for storing URLS. There's basic authentication set up and currently user id 1 is signed in. I want to grab the JSON that's being returned here in the index function which is all the URLs in the database where the user_id matches the authorized user's id:
public function index()
{
$urls = Url::where('user_id', Auth::user()->id)->get();
return Response::json(array(
'error=> false,
'urls' => $urls->toArray()),
200
);
}
I believe JSON is being returned and when I visit my local site http://readitlater.loc/api/v1/url I get an array of objects. On my index page, I have the ng-app directive being defined as an attribute of the html element:
<html lang="en" data-ng-app="">
I have a script defining a constructor function:
<script>
function mainController($scope, $http)
{
$http.get("http://readitlater.loc/api/v1/url/")
.success(function(response) {$scope.urls = response;});
}
</script>
That readitlater.loc/api/v1/url is my route to the index in my API. And when I type it in the browser I get an array of objects which I'm guessing is the JSON being created. For some reason, I can't get it to display in the browser down here:
<body class="container" data-ng-controller="mainController">
<ul class="list-group">
<li class="list-group-item" ng-repeat="address in urls">
{{ address.url }}
</li>
</ul>

As per your comments above, your $scope.urls has urls object and this object contains url key. so you would change your code as follows
<ul class="list-group">
<li class="list-group-item" ng-repeat="address in urls.urls">
{{ address.url }}
</li>
</ul>

It's often handy to validate the variables you are using contain what you think. You can do a console.log or console.dir when you set the value, but displaying them in the HTML right where you are trying to use them can help with scope problems too. Here I would change your code to this:
<pre>{{urls|json}}</pre>
<ul class="list-group">
<li class="list-group-item" ng-repeat="address in urls">
{{ address.url }}
<br/>JSON: {{address|json}}
</li>
</ul>
This should quickly show you that your $scope.urls object looks like this:
{
error:false,
urls: [
{ description: "A Great Blog", id: 2, url: "fideloper.com", user_id: 1 }
]
}
THAT is your $scope.urls object, so when you repeat over it you will get the properties of the object, 'false' and the array that I assume is what you mean by urls:
// Code goes here
var app = angular.module('MyApp', []);
var ctrl = app.controller('MyCtrl', function($scope) {
$scope.name = "Jason Goemaat";
$scope.urls = {
error:false,
urls: [
{ description: "A Great Blog", id: 2, url: "fideloper.com", user_id: 1 }
]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyCtrl">
<h1>Hello, {{name}}!</h1>
<pre>{{urls|json}}</pre>
<ul class="list-group">
<li class="list-group-item" ng-repeat="address in urls">
{{ address.url }}
<br/>JSON: {{address|json}}
</li>
</ul>
</div>
So if you want $scope.urls to be your array, you can set it directly to the urls property on your return object in the $http call:
$http.get("http://readitlater.loc/api/v1/url/")
.success(function(response) {$scope.urls = response.urls;});
Now your ng-repeat will be iterating over the array as I think you intend...
var app = angular.module('MyApp', []);
var ctrl = app.controller('MyCtrl', function($scope) {
$scope.name = "Jason Goemaat";
$scope.urls = [
{ description: "A Great Blog", id: 2, url: "fideloper.com", user_id: 1 }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyCtrl">
<h1>Hello, {{name}}!</h1>
<pre>{{urls|json}}</pre>
<ul class="list-group">
<li class="list-group-item" ng-repeat="address in urls">
{{ address.url }}
<br/>JSON: {{address|json}}
</li>
</ul>
</div>

Related

How to get nested JSON data by using ng repeat in angularjs

I'm trying to getting items._id value in ng view by using ng-repeat.
occurring all data but i want specific data.
data.json
[ { _id : "td6v9db4514cc4ewew4334",
firstName : 'ayaz',
lastName : 'memon',
items : '[{"_id":"item2","_name":"My Item #4"},
{"_id":"item3","_name":"My Item #4"}]',
totalItems : 3,
totalPrice : 2999.97 } ]
Controller
app.controller('myCtrl', function($scope, $http) {
$http.get("data.json").then((response) => {
console.log(response.data)
$scope.userInfo = response.data
})
})
ng view
<body ng-app="myApp">
<div ng-controller="myCtrl">
<ul ng-repeat="x in userInfo">
<li >{{x}}</li>
</ul>
Here you are using nested json object ie items in userInfo, you can write ng-repeat as,
<body ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="x in userInfo.items">{{x._id}}</li>
</ul>
Note: It will be good to understand if you use ng-repeat in <li></li> instead of <ul></ul>
Try using nested ng-repeat like this:
<ul ng-repeat="user in userInfo">
<li ng-repeat="x in user.items">{{x._id}} : {{x._name}}</li>
</ul>
I'm assuming your http call will return a valid response because the Json data you've given is invalid. The keys need to be in enclosed within " ". I've also structured the the ng-repeat assuming that your response will have multiple objects
Try this,
[{
"_id": "td6v9db4514cc4ewew4334",
"firstName": "ayaz",
"lastName": "memon",
"items": [{
"_id": "item2",
"_name": "My Item #4"
},
{
"_id": "item3",
"_name": "My Item #4"
}
],
"totalItems": 3,
"totalPrice": 2999.97
}]
and you could get your repeated "_id" in the items now in ng-repeat="item in userInfo.items" and with {{item._id}} .
Please correct me if there's any mistake, I'm still new.
Thanks.
I was trying to retrieve string as an object that was a mistake. I used object data instead of string and got result.
This is worked for me:
<ul>
<li ng-repeat="user in userInfo">
<ul>
{{user._id}}
<li ng-repeat="item in user.items">
{{item._id}}
</li>
</ul>
</li>
</ul>
Plunker Example:
http://plnkr.co/edit/hzWdj2IiUI2RytYVUI7m?p=preview

Angular, connect objects and display right information

I'm creating an angular webapp, listing different cars in a sidebar and some information about the specific car in a informationbox.
The purpose is to show the right information in the box when clicking the different cars.
I have two different arrays(two API-endpoints), where the first array lists the car name, and the other one got the information about the car. But I have no idea how to connect the objects with the primary key and the foreign key, and how I'm supposed to output the right information after clicking the car.
app.js:
angular.module('myApp', [])
.controller('MyController', function($scope, $http) {
function fetch() {
$http({method : 'GET',url : 'http://*cars*'})
.success(function(data) {
$scope.cars = data;
});
$http({method : 'GET',url : 'http://*information*'})
.success(function(data) {
$scope.information = data;
});
}
fetch();
})
html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
For now all I have done is that I've fetched the data and outputed the cars in the sidebar. But now I've been googling and trying to connect the cars to the information with loops and functions for hours, but stil clueless.
Yes, I'm new to this. Any kind of help would be great! Thanks
You can deal with this with the ng-route. You can do something like :
In your route definition:
.when(/cars/:Id), {
name: 'cars',
templateUrl : 'ayourtemplate.html',
controller : 'yourCtrl'
})
In your html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
The Id will be your key tou will just have to match the right key in your $scope.information
It depends on what information those arrays contains.
If you're sure, that every element corresponds to other, you can just use $index in the html.
<li ng-repeat="name in cars">
{{ name.displayName }}
<p>{{ information[$index] }}</p>
</li>
However, if elements in array aren't ordered, you will have to check primary keys of objects in arrays. Let's assume, that data in arrays looks like this:
cars:
[
{ id: "1", name: "Carrera GT" },
{ id: "2", name: "DB 11" },
... and so on
]
information:
[
{ id: "2", info: "Lorem ipsum" },
{ id: "1", info: "Dolor sit amet" },
...
]
Then I'd suggest using loops and constructing new array using ids.
var carinfo = [];
cars.forEach(car => {
obj["id"] = car.id;
obj["name"] = car.name;
obj["info"] = ""; // Placeholder
info.forEach(c => {
if (c.id === car.id) {
obj["info"] = c.info;
}
});
carinfo.push(obj);
});
$scope.carInfo = carinfo;
Then you can use $scope.carInfo in the html file.
<li ng-repeat="car in carInfo">
{{ car.name }}
<p>{{ car.info }}</p>
</li>

Insert controller from ng-repeat element

I have following problem. I would like to add a controller, whose name is included in the object. Object I receive from ng-repeat.
This is array:
$scope.components = [
{
name: "box",
controller: "BoxCtrl"
}
/*others components*/
];
And this is HTML code:
<ul>
<li ng-repeat="c in components" ng-controller="{{c.controller}}">
{{c.name}}
</li>
</ul>
But I have following
error.
Any ideas how to solve?
The ngController directive expects an instance of a controller but you give him a string.
This should do the job :
In your controller :
$scope.components = [
{
name: "box",
controller: BoxCtrl //Remove the quotes
}
/*others components*/
]
In your view :
<ul>
<li ng-repeat="c in components" ng-controller="c.controller">
{{c.name}}
</li>
</ul>
EDIT: Here is a plunker : http://plnkr.co/edit/sLdZT4UPmgM7Is8SFyrb

Use of Undefined Constant - assumed id

I am new to angularjs and am having some trouble implementing a simple checklist.
<html lang="en" ng-app>
<body>
<div ng-controller="IdController" class="id-contain">
<ul>
<li ng-repeat="id in ids">{{ id.body }}</li>
</ul>
</div>
</body>
</html>
and in my main.js I have
function IdController($scope) {
$scope.id = [
{ body: 'some' },
{ body: 'boiler' },
{ body: 'plate' }
];
}
However, when I load the page, i get Use of undefined constant id - assumed 'id' Any ideas on where I could have gone wrong?
Edit: I have adjusted the name in the controller from $scope.id to $scope.ids to no avail and when I change the {{}} to [[]] it loads [[ id.body ]] 3 times, but not the value. When I run it with {{}} it is giving me the same error and is parsed as <?php echo id.body; ?>
Since many JavaScript frameworks also use "curly" braces to indicate a given expression should be displayed in the browser, you may use the # symbol to inform the Blade rendering engine an expression should remain untouched.
https://laravel.com/docs/8.x/blade#blade-and-javascript-frameworks
Use #before your angular {{}} blocks:
Your code would be like:
<html lang="en" ng-app>
<body>
<div ng-controller="IdController" class="id-contain">
<ul>
<li ng-repeat="id in ids"> #{{ id.body }} </li>
</ul>
</div>
</body>
</html>
That's a problem with blade, you can change laravel's config for blade template token from {{}} to something else like [[]]
Blade::setContentTags('[[', ']]');
Blade::setEscapedContentTags('[[[', ']]]');
Plus, in your angularjs code you should rename $scope.id to $scope.ids in your controller
UPDATE Blade tokens
EDIT OR you can override angular's tags delimiters
DEMO
HTML:
<div ng-app="main">
<div ng-controller="IdController" class="id-contain">
<ul>
<li ng-repeat="id in ids">[[id.body]]</li>
</ul>
</div>
</div>
JS:
angular.module('main', [])
.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
})
.controller('IdController', function ($scope) {
$scope.ids = [
{ body: 'some' },
{ body: 'boiler' },
{ body: 'plate' }
];
});
You html is parsed with the blade parser, if you dont need this page to be parsed with blade parser rename your file from myfield.blade.php to myfile.php

Advanced AngularJS custom filtering on ngRepeat objects

I want to achieve the following theoretical code:
VIEW.html
<li ng-repeat="player in players | filter:myCustomFilter(player)">{{player.name}}
CONTROLLER.js
// some theoretical conditional statement that return a boolean
$scope.otherCondition = true;
$scope.myCustomFilter = function(player) {
return player.name.substring(0,1).match(/A/gi) && $scope.otherCondition;
}
So I want all of my players to be loaded into an Angular model, but I only want to render players into the DOM whose names start with the letter 'A'. When I try and do something like this, my console informs me that player is undefined. Do I need to write a custom filter in order to achieve this (via angular.module().filter())?
Here's a working fiddle: http://jsfiddle.net/orlenko/jV6DK/
Html code (exactly as Karl Zilles suggested):
<div ng-app>
<div ng-controller="MyController">
<h2>Names starting with "A":</h2>
<ul>
<li ng-repeat="player in players | filter:myCustomFilter">{{player.name}}</li>
</ul>
<h2>All Names:</h2>
<ul>
<li ng-repeat="player in players">{{player.name}}</li>
</ul>
</div>
</div>
Javascript:
function MyController($scope) {
$scope.players = [{
name: 'Arthur'
}, {
name: 'William'
}, {
name: 'Bertha'
}, {
name: 'Alice'
}];
$scope.otherCondition = true;
$scope.myCustomFilter = function(player) {
return player.name.substring(0,1).match(/A/gi) && $scope.otherCondition;
}
}
Result
You don't need to pass player to the filter
<li ng-repeat="player in players | filter:myCustomFilter">{{player.name}}
Should work
The answers given are only partially correct, if you need to pass more arguments to the function you would need to create a closure and pass those arguments to the closure as follow:
The 'A' is passed to the closure and player is passed as a part of the context.
HTML:
<div ng-app>
<div ng-controller="MyController">
<h2>Names starting with "A":</h2>
<ul>
<li ng-repeat="player in players | filter:myCustomFilter('A')">{{player.name}}</li>
</ul>
<h2>All Names:</h2>
<ul>
<li ng-repeat="player in players">{{player.name}}</li>
</ul>
</div>
</div>
JS:
function MyController($scope) {
$scope.players = [{
name: 'Arthur'
}, {
name: 'William'
}, {
name: 'Bertha'
}, {
name: 'Alice'
}];
$scope.otherCondition = true;
$scope.myCustomFilter = function(letter) {
return function(player) {
var rgxp = new RegExp(letter, "g");
return player.name.substring(0, 1).match(rgxp) && $scope.otherCondition;
}
}
}
Checkout a working jsfiddle

Categories