I am trying to fetch the data from the JSON, and trying to display it. While fetching the json, it is throwing error in fetch. I am stuck at this point from so many days, and after reading from google, I am confused. Can anyone please help me out what is the error and how to proceed.
<!DOCTYPE html>
<html>
<head>
<title>Fortified Studio</title>
</head>
<body>test
<div id="profiles"></div>
<script id="profileTemplate" type="text/template">
<div class="profile">
<div class="info">
<div class="name">
<%= name %>
</div>
</div>
</div>
</script>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script>
$(function() {
console.log("start of script");
var Prof = Backbone.Model.extend({});
var ProfList= Backbone.Collection.extend ({
model: Prof,
url : '/data/testjson2.json'
});
var ProfView = Backbone.View.extend ({
initialize: function (){
console.log("View initialize");
this.render();
},
render : function (){
console.log("in render");
template: _.template($('#profileTemplate').html()),
_.each (this.collection, function(Prof) {
var profileTemplate = this.template(Prof.toJSON());
$(this.el).append(profileTemplate);
}, this);
console.log (this);
return this;
}
});
var profs = new ProfList ();
var profViews = new ProfView ();
new ProfList().fetch({
sucess : function(){
console.log('json loaded');
},
error: function (){
console.log("error retrieving model");
}
});
profViews.render();
});
</script>
</html>
and my JSON is:-
[
{
"name": "Johny Johny",
},
{
"name": "Jack n Jill",
}
]
and output on console is:-
.......
Unknown property 'box-sizing'. Declaration dropped. myFile.html
"start of script" myFile.html:27
"View initialize" myFile.html:37
"in render" myFile.html:41
[object Object] myFile.html:47
"in render" myFile.html:41
[object Object] myFile.html:47
GET /data/testjson2.json [HTTP/1.1 200 OK 3ms]
syntax error testjson2.json:1
"error retrieving model" myFile.html:62
Please help me out, how to proceed.
Remove the commas at the end of each value set.
[
{
"name":"Johny Johny"
},
{
"name":"Jack n Jill"
}
]
Test your JSON with:
http://jsonformatter.curiousconcept.com/
Related
I have the code below and have 2 separate issues, so please bear with me on this:
Issue 1 [fetch ?]:
The data displayed doesn't change when the JSON change. Sounds like it's a cache issue as I can't see any HTTP request beside the original one. How can I force the JSON file to be downloaded again each time?
Issue 2 [handlebars ?]: with $(document.body).append(html); in the loop, it keeps re-writing the instead of editing the values. How can I change this?
Here is the code:
javascript.js:
async function fetch_json() {
try {
var resp = await fetch('http://localhost:8000/data.json', {mode: 'cors'});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
html page:
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}}
Name : {{name}} Value : {{value}} <br>
{{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{ "name" : "john doe", "value" : "developer" },{ "name" : "bob boby", "value" : "developer2" }];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
//$(document.body).append(html);
})
}, 1000);
var template = document.getElementById('handlebars-demo').innerHTML;
Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$(document.body).append(html);
</script>
any help would be the most appreciated, thank you!
You should create a DOM element to hold the HTML you are generating. I've created <div id="content"></div> in the example.
You can use $().html() to overwrite the HTML each time instead of appending.
$('#content') selects the DOM element with id=content and then overwrite the HTML inside .html(string) with string.
A common approch to cache busting is to attach a timestamp to the url as a url query param, which I have done by concatenating nocache='+new Date().getTime().
In normal use in production a unique identifier is usually generated per version for each resource after building.
// for demo purposes, overwrite value property with username property
jsonify = x => x.json().then(x => x.map(x => ({ ...x,
value: x.username
})));
async function fetch_json() {
try {
// append timestamp to prevent caching
var resp = await fetch('https://jsonplaceholder.typicode.com/users?nocache=' + new Date().getTime(), {
mode: 'cors'
});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.6/handlebars.js" integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8=" crossorigin="anonymous"></script>
<div id="content"></div>
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}} Name : {{name}} Value : {{value}} <br> {{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{
"name": "john doe",
"value": "developer"
}, {
"name": "bob boby",
"value": "developer2"
}];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
$('#content').html(html);
})
}, 2000);
var template = document.getElementById('handlebars-demo').innerHTML;
//Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$('#content').html(html);
</script>
I am learning VueJS 2.0 and I am connecting to an API where I want the value of some data to change on input change. Here is what the output says using the dev tools:
canadianDollar:undefined
europeanEuro:undefined
europeanPound:undefined
usd:"1232"
Whenever I put 1232 in the USD input field it doesn't return anything and leaves those properties as undefined. Here is the code.
new Vue({
el: '#app',
data: {
usd: '',
canadianDollar: '',
europeanPound: '',
europeanEuro: ''
},
// Watch methods
watch: {
usd: function() {
this.convertCurrency()
}
},
// Logic Methods
methods: {
convertCurrency: _.debounce(function() {
var app = this;
if (app.usd.length !== 0) {
// Show that the things are loading in.
app.canadianDollar = 'Searching...'
app.europeanPound = 'Searching...'
app.europeanEuro = 'Searching...'
console.log(app.usd)
axios.get("http://api.fixer.io/latest?base=USD&" + app.usd)
.then(function(response) {
app.canadianDollar = response.data.CAD
app.europeanPound = response.data.GBP
app.europeanEuro = response.data.EUR
})
.catch(function(error){
app.canadianDollar = "ERROR"
app.europeanPound = "ERROR"
app.europeanEuro = "ERROR"
})
}
}, 500)
}
})
and the HTML:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Vue</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" name="" value="" v-model="usd">
<ul>
<li>Canadian Dollar: {{canadianDollar}}</li>
<li>European Pound: {{europeanPound}}</li>
<li>European Euro: {{europeanEuro}}</li>
</ul>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js" charset="utf-8"></script>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
When I type in a number it does give me the "Searching" part but disappears and nothing shows up.
I would recommend changing
then(function(response) {
app.canadianDollar = response.data.CAD
app.europeanPound = response.data.GBP
app.europeanEuro = response.data.EUR
})
to
then(function(response) {
console.log(response);
})
that was you can see what is being returned.
Also, axios.get("http://api.fixer.io/latest?base=USD&" + app.usd) should probably have a name like vulue:axios.get("http://api.fixer.io/latest?base=USD&VALUE=" + app.usd), but you'll have to check their api to see what it is meant to be called.
...
response.data.rates.CAD;
you have
response.data.CAD;
...
app.canadianDollar = response.data.rates.CAD * app.usd;
I have 2 drop downs where selection of first drop down effects the data content of the second drop down.
The problem I have is this functionality is occurring only on first click instead it should happen every time.
Here is my jsFiddle with my working code and here is my code on jsbin(jsbin gives some error which I am unable to understand, help appreciated here too, #newbieTorture).
Thanks in Advance :)
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.ArticleAdapter= DS.FixtureAdapter.extend({});
App.Article =DS.Model.extend({
title: DS.attr(),
body: DS.attr(),
shouldReloadAll:true,
comments: DS.hasMany('comment', {async : true})
//async tells compiler to load data from comment everytime this is rendered
});
App.Comment =DS.Model.extend({
text: DS.attr(),
shouldReloadAll:true,
article: DS.belongsTo('article', { async: true })
});
App.Article.FIXTURES=[
{
id:1,
title : 'Ember',
body:'Its a great technology but need lot of studying and practice',
comments:[1]
},{
id:2,
title : 'Angular',
body:'it takes less understanding but has more coding the ember',
comments:[2,3]
//this will be an aray coz it is has many relation
}
];
App.Comment.FIXTURES=[
{
id:1,
text : 'Yyyieee excited to learn ember',
aricle: 1
//its not an array coz it will be related to single object
},{
id:2,
text : 'I will start Angular once i have fininshed with ember',
article: 2
},{
id:3,
text : 'Angular can be interesting',
article: 2
}
];
App.CommentAdapter= DS.FixtureAdapter.extend();
App.IndexController = Ember.ArrayController.extend({
articleValue: null,
selected: null,
articleStore: Em.computed(function(){
console.log("data is : " + this.get('articleValue'));
console.log("data is : " + this.get('selected'));
return this.store.findAll("article");
}).property("selected"),
availableComment: Em.computed(function () {
var make = this.get('selected');
// the line below returns the id and not an object
console.log(make);
if (make === undefined || make === null)
return [];
return this.get('selected').get('comments');
}).property('articleValue'),
actions:{
callIndexController: function(){
var select= this.get("selected");
console.log("hi :" + select);
}
}
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return [];
},
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
First drop down:
{{
view "select"
contentBinding=articleStore
optionLabelPath="content.title"
optionValuePath="content.id"
prompt="Pick a person:"
shouldReloadAll=true
selectionBinding=selected
valueBinding=articleValue
}}
<br>
<br>
Second drop down:
{{
view "select"
contentBinding=availableComment
optionLabelPath="content.text"
optionValuePath="content.id"
prompt="related task:"
shouldReloadAll=true
valueBinding=articleValue
}}
</script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember.debug.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-data.js"></script>
<script src="js/amit_dropdown.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>
i'm using the auto-complete in tags-input but when i start writing i get this error: array1.filter is not a function. This is my angular call
$scope.loadTags = function(query) {
var searchPeople = $scope.baseUrl + "&searchString=";
return $http.get(searchPeople + query, {
}).success(function (data) {
$scope.people = data.data.data;
console.log($scope.people);
}).error(function (data){
console.log("Error");
});
};
moreover i don't know how to retrieve a value from, in my case $scope.people json that is something like:
{
"id": 17,
"cod": "gg117",
"name": "Alex"
}
i know that i need a custom template but as long as i get the error i can't do it. By the way the template is this one but i don't know if it's correct
<script type="text/ng-template" id="my-custom-template">
<div class="left-panel">
<img ng-src="./img/avatar.jpeg" />
</div>
<div class="right-panel">
<span ng-bind-html="$highlight($getDisplayText())"></span>
<span>({{people.name}})</span>
</div>
</script>
you need to pass a promise, with data of the format
{
"data":[{'text':'tag1'}, {'text', 'tag1'}]
}
I asked question the other day on this app; after some good advice, I moved on and I now think this is a different issue.
Before, I was not getting any display on the screen/no errors or any console.logs. After working on it some more, I now have my model/view and some of my render function working.
I think the issue is with my template or with my append. Below is the full code as it stands now. There are //comments where I think there maybe some issues.
Any help with this would be greatly appreciated.
EDIT :: Thanks for the advice Niranjan. I made some the changes you mentioned; I took away the counter and sample data. With these new changes, my newsFeed.js is no longer being read and so I am unclear as to how to populate my collection. When I console.log out my collection I get an empty array with my defaults shown, but with the json file not being read in the first place how do I get anything to work?
EDIT#2 :: Thank you again Niranjan. With the changes you suggested and a few of my own, I now have the code below. The issue I have right now, Is my array is being populated far too many times. the JSON file has 8 entries in total and because of my _.each statement in my template it is looping 8 times where I only want it to loop once and then to split the array into separate entries. I tried first splitting it during my response parse but this didn't work, do you have any advice for this?
below the code is links to the live views of code and html/broswer content including a link to the JSON file.
My end goal is to click on one title and have the corresponding content show.
(function(){
var NewsFeedModel = Backbone.Model.extend({
defaults: {
title: '',
content: ''
}
});
var NewsFeedCollection = Backbone.Collection.extend({
model: NewsFeedModel,
url : 'newsFeed.js',
parse: function(response) {
console.log('collection and file loaded');
return response.responseData.feed.entries;
}
});
var NewsFeedView = Backbone.View.extend({
el : '.newsContainer ul',
template: _.template($("#feedTemp").html()),
initialize: function(){
var scopeThis = this;
_.bindAll(this, 'render');
this.collection.fetch({
success: function(collection){
scopeThis.render();
}
});
this.collection.bind( 'add', this.render, this);
console.log('View and Template read');
},
render: function () {
this.$el.html(this.template({
feed: this.collection.toJSON()
}));
console.log(this.collection.toJSON());
}
});
var newsFeedCollection = new NewsFeedCollection();
var newsFeedView = new NewsFeedView({
collection: newsFeedCollection
});
var title = newsFeedCollection.find('title');
var content = newsFeedCollection.find('content > title');
$(document).on("click", "#add", function(title, content) {
console.log("I have been clicked");
if($(title) == $(content)){
console.log('they match');
}
else{
console.log('they dont match');
}
$('.hide').slideToggle("slow");
});
}());
This is my underscore template.
<div class="span12">
<script id="feedTemp" type="text/template">
<% _.each(feed, function(data) { %>
<div id = "titleContent">
<%= data.title %>
<div id="content" class="hide">
<%= data.content %>
</div>
</div>
<% }); %>
</script>
</div>
I am using google drive as a testing ground; links for the full html/code.
https://docs.google.com/file/d/0B0mP2FImEQ6qa3hFTG1YUXpQQm8/edit [code View]
https://googledrive.com/host/0B0mP2FImEQ6qUnFrU3lGcEplb2s/feed.html [browser View]
https://docs.google.com/file/d/0B0mP2FImEQ6qbnBtYnVTWnpheGM/edit [JSON file]
There are lot more things in your code that can be improved.
Here is the JSFIDDLE.
Please go through the comments mentioned in the code.
For trying out things in Underscore's template, check Underscore's Template Editor.
Template:
<button id=add>Add</button>
<div class="newsConatiner">
<ul></ul>
</div>
<script id="feedTemp">
<% _.each(feed, function(data) { %>
<div id = "titleContent">
<h2> <%= data.title %> </h2>
<div id="content">
<%= data.content %>
</div>
</div>
<% }); %>
</script>
Code:
(function () {
var NewsFeedModel = Backbone.Model.extend({
//url: 'newsFeed.js',
defaults: {
title: '',
content: ''
}
});
var NewsFeedCollection = Backbone.Collection.extend({
model: NewsFeedModel,
url: 'newsFeed.js',
parse: function (response) {
console.log('collection and file loaded');
return response.responseData.feed.entries;
}
});
var NewsFeedView = Backbone.View.extend({
el: '.newsConatiner',
//template should not be inside initialize
template: _.template($("#feedTemp").html()),
initialize: function () {
_.bindAll(this, 'render');
this.render();
//ADD event on collection
this.collection.bind('add', this.render, this);
console.log('View and Template read');
},
/*
This initialize will fetch collection data from newsFeed.js.
initialize: function () {
var self = this;
_.bindAll(this, 'render');
this.collection.fetch({
success: function(collection){
self.render();
}
});
//ADD event on collection
this.collection.bind('add', this.render, this);
console.log('View and Template read');
},
*/
render: function () {
//This is how you can render
//Checkout how this.collection is used
this.$el.html(this.template({
feed: this.collection.toJSON()
}));
}
});
//Initialized collection with sample data
var newsCounter = 0;
var newsFeedCollection = new NewsFeedCollection([{
title: 'News '+newsCounter++,
content: 'Content'
}]);
//Created view instance and passed collection
//which is then used in render as this.collection
var newsFeedView = new NewsFeedView({
collection: newsFeedCollection
});
$('#add').click(function(){
newsFeedCollection.add(new NewsFeedModel({
title: 'News ' + newsCounter++,
content: 'Content'
}));
});
}());