Grab an array within imported JSON object - AngularJS - javascript

I am building a quick Angular app that uses a service to grab a JSON from a URL.
The JSON structure looks like this:
{news:[{title:"title",description:'decription'},
{title:"title",description:'decription'},
{title:"title",description:'decription'}
]};
What I need is just the array within the news object.
My code to import the JSON is as follows:
app.factory('getNews', ['$http', function($http) {
return $http.get('URL')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
Then to add the data to the $scope object in the controller I do this:
app.controller('MainController', ['$scope','getNews', function($scope, getNews) {
getNews.success(function(data)) {
$scope.newsInfo = data.news;
});
});
But it doesn't work. When I load the html page, there is only white. My thinking is that this is because it isn't grabbing the array within the JSON and using that data to populate the HTML directive I set up.
newsInfo.js:
app.directive('newsInfo',function(){
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl:'newsInfo.html'
};
});
newsInfo.html:
<h2>{{ info.title }}</h2>
<p>{{ info.published }}</p>
My HTML doc is:
<head>
<title></title>
<!--src for AngularJS library-->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
</head>
<body ng-app="THE APP NAME"> <!--insert ng app here-->
<div ng-controller="MainController"> <!--insert ng controller here-->
<div ng-repeat="news in newsInfo"><!--insert ng repeat here-->
<!-- directive goes here-->
<newsInfo info="news"></newsInfo>
</div>
</div>
<!-- Modules -->
<script src="app.js"></script>
<!-- Controllers -->
<script src="MainController.js"></script>
<!-- Services -->
<script src="getNews.js"></script>
<!-- Directives -->
<script src="newsInfo.js"></script>
</body>
Thoughts?

Change
<newsInfo info="news"></newsInfo>
to
<news-info info="news"></news-info>
example: https://jsfiddle.net/bhv0zvhw/3/

You haven't specified the controller.
<div ng-controller="MainController"> <!--insert ng controller here-->
<div ng-repeat="news in newsInfo"><!--insert ng repeat here-->
<!-- directive goes here-->
<newsInfo info="news"></newsInfo>
</div>
</div>

$scope.getNews = function(){
return $http.get('URL').success(function(data) {
return data.news;
})
};
^ This, just change it so that the success function returns only the news!

While I am answering my own question, I should point out that everyone's answers were also correct. The code had multiple errors, but the final error was fixed by doing the following:
Apparently I had to upload the newsInfo.html doc to an S3 bucket and use that URL as “Cross origin requests are only supported for HTTP.” But then Angular blocked that external source with the Error: "$sce:insecurl Processing of a Resource from Untrusted Source Blocked".
So since the html template was so simple, i just bipassed this issue by typing in the template directly into the .js directive and it worked! thanks everyone for the help!

Related

Show HTML elements in JSON with Angular js

I am new in angular js, I am trying to format a json data with angular js.
Here is my json data
[
{"field_add_link": "Home"},
{"field_add_link": "About Us"}
]
here is my conroller
var myApp = angular.module('myApp', ['ngSanitize']);
myApp.controller('myController',function($scope, $http) {
$http.get('http://localhost/drupal3/menu')
.then(function(response) {
$scope.links = response;
});
});
and finally here is how i am fetching the json data with angular
<div class="col-md-8 content" ng-controller ="myController">
<div class="col-md-12" ng-repeat="link in links" ng-bind-html="links">
<p>{{ link.field_add_link }}</p>
</div>
</div>
no output was shown after this, giving an error Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context. in the browser's console
but when I used ng-bind-html="links[0].field_add_link instead of ng-bind-html="links" and <p>{{ link[0].field_add_link }}</p> instead of <p>{{ link.field_add_link }}</p>
then i get Home as output 'without interpreting the tag'
Pls, how do I go about this?
First of all you dont need the ng-bind-html attribute on your div with ng-repeat. It should be on your p tag. Second, you need to bind link (the current element of the ng-repeat-loop) not links (the array). Although you need to look into the error [$sce:unsafe]. HTMl can only be bind to an element-body if it is trusted. For that you need to have, for example, a filter.
myApp.filter ('to_trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml (text);
};
}]);
<div class="col-md-8 content" ng-controller ="myController">
<div class="col-md-12" ng-repeat="link in links">
<p ng-bind-html="link.field_add_link | to_trusted"></p>
</div>
</div>
You just need to move your ng-bind-html from div to <p> like following code.
<p ng-bind-html="link.field_add_link"></p>
var myApp = angular.module('myApp', ['ngSanitize']);
myApp.controller('myController', function($scope, $http) {
var data = [{"field_add_link": "Home"},
{"field_add_link": "About Us"}];
$scope.links = data;
//For demo, removed the http call
});
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-sanitize.js"></script>
</head>
<body ng-app="myApp">
<div class="col-md-8 content" ng-controller="myController">
<div class="col-md-12" ng-repeat="link in links">
<p ng-bind-html="link.field_add_link"></p>
</div>
</div>
</body>

How to dynamically load the pop-up window in AngularJS?

Web project: backend - ASP.NET, frontend - AngularJS.
I have the "main page" with mainApp module.
Also i have the another page with the registration, which is the responsibility of LoginLayerApp.
What i want: when you click on "main window" i need pop-up window with the registration content (html, css, angularController and so on).
What was tried:
Loaded using JQuery, implement the DOM and call angular.bootstrap by
hands.
Loaded via $http and using ngDialog library to open a pop-up
window.
Use the iframe.
The problem is that the loaded naked HTML, but I do not know how to inject LoginLayerApp, to then rebuild the naked HTML. I can do it only once, but not as usual, when angular always rebuild view by changes in controller (for example, different ng-class depending on the width of the screen).
How to do the most right? Perhaps I should do differently to organize something?
RequireJS, WebPack will not work, too much legacy-project implementation for such a trifle.
Example of registration page:
#using Inventum.ViewModels.Account
#using Microsoft.Owin.Security
#{
Layout = null;
}
<link href="~/Content/css/layers/Login/loginRegistrationLayer.min.css" rel="stylesheet" />
<div ng-app="loginLayerApp"
ng-controller="loginLayerController as loginCtrl"
ng-init="init(); returnUrl = '#ViewBag.ReturnUrl'; type = ('#ViewBag.Type' == '') ? 'login' : '#ViewBag.Type'; form={}; user={};"
esc-key="closeLayer()"
class="login-app-container"
tabindex="0">
<div class="container" ng-class="{'mobile': !desktop, 'desktop': desktop }" ng-switch on="type">
<!-- =============== LOGIN =============== -->
<div class="registration-container" ng-switch-when="login">
{{loginCtrl.desktop}}
{{desktop}}
<h1>#Html.ClickZone("NewRegLogin.Login.Title")</h1>
<div class="main-label">
<span>#Html.ClickZone("NewRegLogin.Login.HelpLabel")</span>
<br ng-show="phoneBreakpoint">
</div>
<!-- ======== Errors block ======== -->
<!-- ======== Errors block ======== -->
<div class="options">
<ng-form name="form.userForm" ng-class="{'showMe': nosocial && !desktop}" novalidate enter-key="trySubmit = true; submitForm(form.userForm.$valid, user)">
<!-- <form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> -->
<div class="emailFocusHandler" ng-hide="desktop || nosocial" ng-click="nosocial = true;"></div>
<div class="group">
</div>
<div ng-show="desktop || nosocial">
<div class="group">
</div>
<div class="help-buttons">
</div>
<div class="error-block" ng-if="loginFailed && answerCode == ANSWERS.LOGIN.UserNoutFound">
</div>
<button type="submit" ng-click="trySubmit = true; submitForm(form.userForm.$valid, user)">#Html.ClickZone("NewRegLogin.SignIn") </button>
</div>
</ng-form>
<div class="delimeter" ng-show="desktop || nosocial"></div>
</div>
</div>
<!-- =============== LOGIN =============== -->
</div>
#section scripts {
<!-- ANGULARJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.min.js"></script>
#Scripts.Render("~/bundles/js/layer/newLogin")
<script src="https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit" async defer></script>
}
What I would do is create the modal window (pop-up window) as a angular-ui modal. (their modal docs). That way you don't have to write your own modal code.
When you implement it, the modal will get its own controller and its own html file and the implementation will look like this:
Current Controller-
appName.controller('loginLayerController', ["$scope","uibModal", function ($scope, $uibModal){
$scope.openComponentModal = function () {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'myModalController',
controllerAs: 'myModalController'
}
});
}])
And from there you can put your form into myModalContent.html, and hide and show buttons there accordingly
I'm not sure, but you can try to create component, that will show your errors. By default set in invisible. In controllers you can manage how many and when you should show your error messages.

Use variable as expression in ng-include

This code works:
<div ng-include src="'Test.html'"></div>
This code doesn't:
<div ng-include src="ctrl.URL"></div>
(ctrl.URL is set to "Test.html"). I also set it to 'Test.html' and "'Test.html'" with the same results.
How can I successfully convert this into an expression for use in ng-include src? I think I am missing some knowledge on how strings get parsed but I was pretty sure 'Test.html' should work.
I found that I am too incompetent to rename my own variables. ctrl.URL was really ctrl.URl. Now everything is working.
Check this, maybe this fiddle will help you.
HTML and templates:
<div ng-controller="Ctrl">
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
url of the template: <tt>{{template.url}}</tt>
<hr/>
<div ng-include src="template.url" onload='myFunction()'></div>
</div>
<!-- template1.html -->
<script type="text/ng-template" id="template1.html">
Content of template1.html
</script>
<!-- template2.html -->
<script type="text/ng-template" id="template2.html">
<p ng-class="color">Content of template2.html</p>
</script>
The controller:
function Ctrl($scope) {
$scope.templates = [{
name: 'template1.html',
url: 'template1.html'},
{
name: 'template2.html',
url: 'template2.html'}];
$scope.template = $scope.templates[0];
$scope.myFunction = function() {
$scope.color = 'red';
}
}

get webpage URL(moving to other page without changing URL)

Website address is http://bbn.kiwoom.com/bbn.corpAnalCRList.do (is not my site)
I want to get the webpage URL (pic 2) that you can move by clicking red box or calling js function(green box) like pic 1.
pic1&pic2
But the page URL doesn't change. I want to provide the page link(a tag) for other people at my website.
How to get the page URL (pic 2)? or Is there other solution for the page link(a tag) like using javascript function?
Thanks.
I think what you want, you can do easily with angular ng-include or object/iframe:
(function(angular) {
'use strict';
angular.module('includeExample', ['ngAnimate'])
.controller('ExampleController', ['$scope', function($scope) {
$scope.templates =
[ { name: 'pic1.html', url: 'https://www.google.com.br'},
{ name: 'pic2.html', url: 'http://www.google.com.br'} ];
$scope.template = $scope.templates[0];
}]);
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-animate.js"></script>
<body ng-app="includeExample">
<div ng-controller="ExampleController">
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
url of the template: <code>{{template.url}}</code>
<hr/>
<div class="slide-animate-container">
<div class="slide-animate" ng-include="template.url"></div>
<object type="text/html" data="{{template.url}}"
style="width:100%; height:100%; margin:1%;">
</object>
</div>
</div>
</body>
(blank)
url of the template: {{template.url}}
https://docs.angularjs.org/api/ng/directive/ngInclude
You can use client routing - changing the url hash tag. Look at this small js library http://sammyjs.org/
You define your detail route, handling this route you will be showing your detail.

delay including of html files in angularjs ng-include

I have a series of html files I am including into my main controller. These html files are not actually being used for atleast 4 seconds while one html file does its stuff. How would I define to delay loading of rest of the files to improve startup performance of the app.
<div ng-app="myApp" ng-controller="myController" >
<div ng-include="somefile.html" ></div>
<!-- More files to include -->
</div>
Another solution(less elegant) could be:
<div ng-app="myApp" ng-controller="myController" >
<div ng-include="template" ></div>
<!-- More files to include -->
</div>
In your controller initialize template with
$scope.template = '';
And do
$scope.template = 'somefile.html';
when you need the template to be loaded.
Load these asynchron with promises. This covers the idea:
var promise = $http.get('someFile.html').success(function (data) {
htmlContent = data.response;
});
promise.then(function(result) {
$scope.model = result;
});

Categories