I am trying to learn how to work with angular and javascript more. Please let me know what I am doing wrong here.
When I input something into the text box, it should display
"hello {name} , would you like to play a game?
It displays the string without the input.
Also, when I run it, it says
object Object
.
(function (app) {
var JakesController = function ($scope, $http) {
$scope.JakesSampleModel = {name: ' '};
$scope.theSampleReturn = null;
var sendResponseData = function (response) {
if (response.data.error) {
console.log(data);
}
else {
$scope.theSampleReturn = response.data;
}
};
var sendResponseError = function (data) {
console.log(data);
}
$scope.senddata = function (params) {
return $http({
method: 'post',
url: '/home/servercall',
data: params
})
.then(sendResponseData)
.catch(sendResponseError);
};
};
app.controller("JakesController",['$scope', '$http', JakesController]);
}(angular.module("JakesFirstApp")));
Here is the HTML:
<div id="OutterDiv" ng-controller="JakesController" ng-app="JakesFirstApp">
<div id="JakesButton" class="button" ng-click="senddata()">Submit</div>
<input type="text" id="JakesTextBox" ng-model="theSampleReturn" />
{{theSampleReturn.result}}
Json result:
public JsonResult servercall(string name)
{
return Json(new { result = $"Hello {name}, Would you like to play a game?" }, JsonRequestBehavior.AllowGet);
}
In your html try to use {{theSampleReturn}} instead of {{theSampleReturn.result}} because you don't seem to have theSampleReturn.result set anywhere
If I understand you question correctly, then it looks like the solution is to update your template like so:
<input type="text" id="JakesTextBox" ng-model="JakesSampleModel.name" />
And then update your controller to correctly send the name to the server when senddata() is called:
$scope.senddata = function () {
// Construct params for post by getting data from your scope/model that's
// wired up to your input field
var params = { name : $scope.JakesSampleModel.name };
return $http({
method: 'post',
url: '/home/servercall',
data: params
})
.then(sendResponseData)
.catch(sendResponseError);
};
Related
I am new to Knockout JS and think it is great. The documentation is great but I cannot seem to use it to solve my current problem.
The Summary of my Code
I have two viewmodels represented by two js scripts. They are unified in a parent js file. The save button's event is outside
both foreach binders. I can save all data in the details foreach.
My Problem
I need to be able to include the value from the contacts foreach binder with the values from the details foreach binder.
What I have tried
I have tried accessig the data from both viewmodels from the parent viewmodel and sending the POST request to the controller from there but the observeableArrays show undefined.
Create.CSHTML (Using MVC5 no razor)
<div id="container1" data-bind="foreach: contacts">
<input type="text" data-bind="value: contactname" />
</div>
<div data-bind="foreach: details" class="card-body">
<input type="text" data-bind="value: itemValue" />
</div>
The save is outside of both foreach binders
<div class="card-footer">
<button type="button" data-bind="click: $root.save" class="btn
btn-success">Send Notification</button>
</div>
<script src="~/Scripts/ViewScripts/ParentVM.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel1.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel2.js" type="text/javascript"></script>
ViewModel1
var ViewModel1 = function (contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (contact) {
return {
contactName: contact.contactName
};
}));
}
ViewModel2
var ViewModel2 = function (details) {
var self = this;
self.details = ko.observableArray(ko.utils.arrayMap(details, function (detail) {
return {
itemNumber: detail.itemValue
};
}));
}
self.save = function () {
$.ajax({
url: baseURI,
type: "POST",
data: ko.toJSON(self.details),
dataType: "json",
contentType: "application/json",
success: function (data) {
console.log(data);
window.location.href = "/Home/Create/";
},
error: function (error) {
console.log(error);
window.location.href = "/Homel/Create/";
}
});
};
ParentViewModel
var VM1;
var VM2;
var initialContactInfo = [
{
contactPhone: ""
}
]
var initialForm = [
{
itemValue: ""
]
}
$(document).ready(function () {
if ($.isEmptyObject(VM1)) {
ArnMasterData = new ViewModel1(initialContactInfo);
ko.applyBindings(VM1, document.getElementById("container1"));
}
if ($.isEmptyObject(VM2)) {
VM2 = new ViewModel2(initialForm);
ko.applyBindings(VM2, document.getElementById("container2"));
}
});
I'm trying to implement something with jQuery and Vue.js:
And here is my script part:
<script>
function initVM(result) {
// alert(result.num)
var vm2 = new Vue({
el: '#vm2',
data: {
// ③bind one item of the result as example
rrr: result.num
}
});
$('#vm2').show();
}
$(function() {
var vm = new Vue({
el: '#vm',
data: {
content: ''
},
methods: {
submit: function(event) {
event.preventDefault();
var
$form = $('#vm'),
content = this.content.trim();
// ①post textarea content to backend
$form.postJSON('/api/parse', {
content: content
}, function(err, result) {
if (err) {
$form.showFormError(err);
}
else {
// ②receive a result dictionary
$('#vm').hide();
initVM(result);
}
});
}
}
});
});
</script>
Here is my html part:
<html>
<form id="vm", v-on="submit: submit">
<textarea v-model="content" name="content"></textarea>
<button type="submit">Have a try!</button>
</form>
<div id="vm2" style="diplay:none;">
<!-- ④show the result-->
The result:
{{ rrr }}
</div>
</html>
Here is the definition of postJSON
<script>
// ...
postJSON: function (url, data, callback) {
if (arguments.length===2) {
callback = data;
data = {};
}
return this.each(function () {
var $form = $(this);
$form.showFormError();
$form.showFormLoading(true);
_httpJSON('POST', url, data, function (err, r) {
if (err) {
$form.showFormError(err);
$form.showFormLoading(false);
}
callback && callback(err, r);
});
});
// ...
// _httpJSON
function _httpJSON(method, url, data, callback) {
var opt = {
type: method,
dataType: 'json'
};
if (method==='GET') {
opt.url = url + '?' + data;
}
if (method==='POST') {
opt.url = url;
opt.data = JSON.stringify(data || {});
opt.contentType = 'application/json';
}
$.ajax(opt).done(function (r) {
if (r && r.error) {
return callback(r);
}
return callback(null, r);
}).fail(function (jqXHR, textStatus) {
return callback({'error': 'http_bad_response', 'data': '' + jqXHR.status, 'message': 'something wrong! (HTTP ' + jqXHR.status + ')'});
});
}
</script>
The process can be described as:
Post the content to backend
Receive the result and hide the form
Create a new Vue with the result
Show the result in a div which is binding with the new Vue instance
Actually, I do receive the result successfully, which is proved by the alert(result.num) statement, but nothing find in vm2's div except The result:
Where is the problem? Or please be free to teach me a simpler approach if there is, because I don't think what I am using is a good one.
Here's questioner.
Finally I found where is the problem.
The problem lays in Mustache: {{ }}
I use jinja2, a template engine for Python and Vue.js, a MVVM frontend framework. Both of them use {{ }} as delimiters.
So if anyone got trapped in the same situation with me, which I don't think there will be, please:
app.jinja_env.variable_start_string = '{{ '
app.jinja_env.variable_end_string = ' }}' # change jinjia2 config
OR
Vue.config.delimiters = ['${', '}'] # change vue config
Hi I have a simple controller where it passes unique integers into my url, but Im running to many issues. I need to change this "4401" dynamically from my controller.
the url Im trying to reach:
https://itunes.apple.com/us/rss/topmovies/limit=50/genre=4401/json
app.factory('classic',function ($resource) {
return $resource('https://itunes.apple.com/us/rss/topmovies/limit=50/genre=:id/json', {
get: {
method: 'JSONP',
id: '#id'
}
});
});
and here is my controller
app.controller('TestCrtl', function ($scope, classic) {
init();
function init(id) {
$scope.movies = classic.get(id);
}
$scope.classicMovies = function(){
var id = "4403";
init(id);
}
$scope.anctionMovies = function(){
var id = "4404";
init(id);
}
});
The error Im getting
Uncaught SyntaxError: Unexpected token :
any help would be highly appreciated.
<div class="col-sm-4">
<button type="button" data-ng-click="actionMovies()" class="btn btn-default">Action</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-default">Scary</button>
</div>
I believe this is the correct way to implement parameters when using a resource factory:
app.factory('movieService',function ($resource) {
return $resource('https://itunes.apple.com/us/rss/topmovies/limit=50/genre=:id/json', {id: '#id'}, {
query: { method: 'GET', isArray:true, params: {id: '#id'} }
});
});
This can be simplified to:
app.factory('movieService',function ($resource) {
return $resource('https://itunes.apple.com/us/rss/topmovies/limit=50/genre=:id/json', {id: '#id'});
});
To call this get method you would need to do the following. Note the parameters that are used in the get method.
app.controller('TestCrtl', function ($scope, movieService) {
$scope.classicMovies = function(){
movieService.query({id: 4403}, function(result){
$scope.movies = result;
});
}
$scope.anctionMovies = function(){
movieService.query({id: 4404}, function(result){
$scope.movies = result;
});
}
});
Additionally, it should be noted that the resource method call is going to return a promise. You can either set it from the return value of the get method, like you did above (The status of the promise isn't guaranteed), or you can set it in the callback, which guarantees that the promise is resolved.
Try this:
app.factory('classic',function ($resource) {
return $resource('https://itunes.apple.com/us/rss/topmovies/limit=50/genre=:id/json', {
get: {
method: 'JSONP',
id: '#id'
}
});
});
And in controller change to :
$scope.movies = classic.get(id);
i am using the below format to get a JSON object from my localhost. The JSON is pretty complicated and lengthy so , using jquery to populate the HTML is getting complicated.
function processmsg(msg) {
var jobj = JSON.parse(msg);
if (typeof jobj === 'object')
{
// Parse the JSON
}
document.getElementById("messages").innerHTML = globalTag;
}
}
function waitForMsg() {
$.ajax({
type: "GET",
url: "1.json",
cache: false,
timeout: 50000,
success: function (data) {
processmsg(data);
if (!data) {
setTimeout(
waitForMsg,
1000
);
};
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
setTimeout(waitForMsg, 15000);
processmsg("error");
}
});
};
$(document).ready(function () {
waitForMsg();
processmsg("loading");
});
I would like to use the format like {{jobj.entries}}. something like this. This can be done on angularJS. can you guys please suggest me how to do the same in angular ?
i want to query the JSON every 1 min and when the data is found i want to cancel the interval. I dono how to do it in angularjs.
==================update================
i got below code snippet. It is working fine, But how do i stop the url query once the json object is obtained..
var app = angular.module('urlanalyzer', []);
app.controller('jsonController', function($scope, $http) {
$scope.getData = function(){
var url = "{% static "" %}tmp/{{url_hash}}/{{url_json}}";
$http.get(url)
.success(function(data, status, headers, config) {
console.log(data);
});
};
if (!$scope.data){
setInterval($scope.getData, 2000);
}
The issue here is the json object will be available after 3 sec only.
var app = angular.module('urlanalyzer', []);
app.controller('jsonController', ['$scope','$http','$timeout',function($scope, $http, $timeout) {
$scope.getData = function(){
var url = "{% static "" %}tmp/{{url_hash}}/{{url_json}}";
$http.get(url)
.success(function(data, status, headers, config) {
if(!data)
$timeout(function(){
$scope.getData()
}, 2000)
else{
$scope.myData = data.data? data.data:data;
$scope.showError = false;
}
})
.error(function(msg) {
$timeout(function(){
$scope.getData()
}, 2000)
$scope.processMessage(msg)
});
};
$scope.processMessage = function(msg){
if(angular.isString(msg))
$scope.errorMessage = msg;
else if(angular.isObject(msg)){
$scope.errorMessage = msg.message // the property you want;
}
$scope.showError = true;
}
$scope.getData();
}])
HTML:
<div ng-controller="jsonController">
<div ng-show="showError">
{{errorMessage}}
</div>
<div id="myDatacontainer">
//you can bind any propery of your data by using angular direvtives
//look at ng-bing, ng-if etc. directives
{{myData.name}} ...
</div>
</div>
Hope it help.
Consider you have following JSON data stored in a scope variable named data:
$scope.data = {
"array": [
1,
2,
3
],
"boolean": true,
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
Then you write your HTML in the following way like:
<div>
Boolean: {{data.boolean}}
</div>
<div>
Number: {{data.number * 2}}
</div>
<div>
Array:
<p ng-repeat="(key, value) in data.object"> {{key}} : {{value}}</p>
</div>
Another way to bind <div ng-bind="data.string"></div>
Here you can stop your call. You can use enhanced angular service $interval for this:
$scope.getData = function(){
var url = "{% static "" %}tmp/{{url_hash}}/{{url_json}}";
$http.get(url)
.success(function(data, status, headers, config) {
console.log(data);
$interval.cancel($scope.intervalObject); // cancel the interval when data is loaded
});
};
if (!$scope.data){
$scope.intervalObject = $interval($scope.getData, 2000);
}
if (!$scope.data){
setInterval($scope.getData, 2000);
}
since $scope.data is not set it'll continue calling the request(since you are not setting $scope.data anywhere).
Edit: Also, use angularjs $interval since it's the angular way of using setInterval and it keeps track of the $digest cycle
I am having trouble trying to append a new url parameter after selecting a genre to create a request to the API.
My ng-change is genreChange. When it been selected, it should automatically append the new url parameter like this &with_genre=fiction in the $scope.movies url before submitting the form with submitButton
<form ng-submit="submitButton()" name="cForm" class="form-horizontal">
<h2>Discover the gems</h2>
<div class="form-group">
<select class="form-control" ng-model="genreSelect" ng-change="genreChange()">
<option ng-repeat="genre in genreList.genres" value="{{genre.id}}">{{genre.name}}</option>
</select>
</div>
<input type="submit" value="hello" />
</form>
-
$scope.genreChange = function() {
$scope.genreVar = $scope.genreSelect;
$scope.movies.get({with_genres: $scope.genreVar});
}
$scope.movies = $resource('http://api.themoviedb.org/3/discover/movie:action', {
api_key: apikey,
callback: 'JSON_CALLBACK'
}, {
get: {
method: 'JSONP'
}
});
$scope.submitButton = function() {
$scope.films = $scope.movies.get();
}
I am doing this method just in case a user leaves it blank.
Thanks
This is what Resource.bind does.
var MovieResource = $resource('http://api.themoviedb.org/3/discover/movie:action', {
api_key: apikey,
callback: 'JSON_CALLBACK'
}, {
get: {
method: 'JSONP'
}
});
$scope.movies = MovieResource;
$scope.genreChange = function() {
$scope.genreVar = $scope.genreSelect;
$scope.movies = MovieResource.bind({with_genres: $scope.genreVar})
}
$scope.submitButton = function() {
$scope.films = $scope.movies.get();
}