I'm trying to create a search of the rotten tomatoes api using angularjs. I want to be able to type the query press enter or go (on a phone) then the api returns the result of the query.
I tried to attach the $scope.search to an input in the view. I know I'm doing something wrong but due to my inexperience I can't think what to do. Looking for someone to kindly point me in the right direction.
View
<input placeholder="Search for it" ng-model="search">
Controller
ctrls.controller('resultsCtrl', function($scope, $http){
$scope.search = 'query';
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies.json', {
params: {
page_limit: '5',
page: '1',
q: $scope.search,
apikey: myKey,
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.results = data.movies;
});
});
You will have to use a function for that
ctrls.controller('resultsCtrl', function($scope, $http){
$scope.search = 'query';
$scope.fetchResults = function(){
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies.json', {
params: {
page_limit: '5',
page: '1',
q: $scope.search,
apikey: myKey,
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.results = data.movies;
});
}
});
and call it from your view
<form ng-submit="fetchResults()">
<input placeholder="Search for it" ng-model="search">
<input type="submit" value="Go"/>
</form>
Related
I am building an application where I need to get the value return from the API and bind it to my variable. I have been stuck on this for days, and I couldn't go any further.
Here is my code:
<script>
let address = "";
async function addExample() {
const response = await fetch(
"https://api",
{
method: "PUT",
headers: {
"api-key":
"api-key",
},
body: JSON.stringify({
address: address,
}),
}
);
}
</script>
<svelte:head>
<script
src="https://maps.googleapis.com/maps/api/js?key=my-key&libraries=places&callback=initAutocomplete"
async
defer
>
</script>
<script>
let autocomplete;
function initAutocomplete() {
const input = document.getElementById("autocomplete");
const options = {
componentRestrictions: { country: "au" },
strictBounds: false,
};
const autocomplete = new google.maps.places.Autocomplete(
input,
options
);
}
autocomplete.addListener("place_changed", onPlaceChanged);
function onPlaceChanged() {
address = autocomplete.getPlace();
}
</script>
</svelte:head>
<input
id="autocomplete"
placeholder="address"
type="text"
bind:value={address}
/><br />
I tried to add my tag svelte:head inisde the script tag but it didn't work, among others tries. And due my lack of experience, I want if I'm doind this on the right way instead of waste more time on this. PS: I don't need to create a map or anything like that now. I just want to bind the value of autocomplete to my variable, so I will be able to fetch data into DB.
I have tried eveything I could find googling but none of them worked. I am newbie with all this, and I don't know what else to think/try.
To begin with, I'm making a simple social media application. I'm trying to submit a form which has text, images, and videos. My frontend where the form is submitted is made with React and server is ran with node.js mounted on nginx. I was trying to append the inputted files into FormData with code below:
handleSubmit = function (e) {
e.preventDefault();
const formData = new FormData();
formData.append("textBody", this.state.textBody)
for (let i = 0; i < this.state.imgInput.length; i++) {
formData.append("imgInput", this.state.imgInput.files[i], "img"+i.toString())
fetch("mywebsite.com/api/submitArticle", {
body: formData,
method: "POST",
credentials: 'include',
}).then((response) => console.log(response))
return false;
}.bind(this)
handleChange = function (e) {
e.preventDefault();
if (e.target.name === 'imgInput') {
this.setState({
imgInput: e.target.files,
showSpan: false
})
}
}.bind(this)
<form onSubmit={this.handleSubmit}>
<textarea id='textBody' name='textBody' onFocus={removeSpan} onBlur={checkSpanOn} onChange={this.handleChange}/>
<input type="file" id="imgInput" name="imgInput" accept="image/*" ref={this.imgRef} multiple={true} onChange={this.handleChange}/>
<input type="submit" id="submitButton" name="submitButton" formEncType="multipart/form-data" />
</form>
But React gave me this error upon submitting the form:
TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'.
at "formData.append("imgInput", this.state.imgInput.files[i], "img"+i.toString())".
So when I console logged what e.target.files before setState in handleChange, I got normal FileList with all the image files listed. But when I console loggedd this.state.imgInput after setState in handleChange, I got String of C://fakepath/filename, not fileList. (Initially state.imgInput was null. When I saw other examples and codes, e.target.files was fileList so I'm puzzled elsewhere I made mistake.
I was spending half my day on this problem and I'm 5 sec before fainting so any advice would be appreciated :) Thank you for reading.
yes this happening because the event is gone you need to store the event.target in variable + the files will be in imgInput not imgInput.files so here it is:
handleSubmit = e => {
e.preventDefault();
const formData = new FormData();
formData.append("textBody", this.state.textBody);
for (let i = 0; i < this.state.imgInput.length; i++) {
formData.append("imgInput", this.state.imgInput[i], "img" + i.toString());
fetch("mywebsite.com/api/submitArticle", {
body: formData,
method: "POST",
credentials: "include"
}).then(response => console.log(response));
}
};
handleChange = e => {
e.preventDefault();
const target = e.target;
if (target.name === "imgInput") {
this.setState(current => ({
...current,
imgInput: target.files,
showSpan: false
}));
}
};
I am not able to pass data to controller's function through angular directive, directive has one change event. In which i want to pass my dynamic id.
In controller i have myArray
$scope.myArray = [1,2,3,4,5];
I have following html.
<div ng-repeat="data in myArray track by $index">
<input type="file" ng-upload-change="uploadFile($event, $id)" my-id="$index">
<div>
In Controller:
$scope.uploadFile = function($event, $id){
var files = $event.target.files;
console.log("id:"+$id);
};
In directive:
app.directive('ngUploadChange', function() {
return{
scope:{
ngUploadChange:"&",
myId:"="
},
link:function($scope, $element, $attrs){
$element.on("change",function(event){
$scope.ngUploadChange({$event: event, $id : $scope.myId});
})
$scope.$on("$destroy",function(){
$element.off();
});
}
}
});
As you can see that when i pass uploadFile function to ngUploadChange directive, it always pass first id (in this case it is 1) to controllers function.
I am not getting updated id every time.
Thanks in advance.
When you want to pass parameters through the function, you can use "=" instead of "&" for that attr binding, and in your HTML, you can specify like this:
<input type="file" ng-upload-change="uploadFile" ... />
And, I changed the way you were passing an object of params since there is no need to create that object.
Now, if you see the code snippet below, it correctly logs id: x (0-based) on each file upload.
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
myApp.controller('MyCtrl', function MyCtrl($scope) {
$scope.myArray = [1, 2, 3, 4, 5];
$scope.uploadFile = function($event, $id) {
var files = $event.target.files;
console.log("id: " + $id);
};
});
myApp.directive('ngUploadChange', function() {
return {
scope: {
ngUploadChange: "=",
myId: "="
},
link: function($scope, $element, $attrs) {
$element.on("change", function(event) {
$scope.ngUploadChange(event, $scope.myId);
})
$scope.$on("$destroy", function() {
$element.off();
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="data in myArray">
<input type="file" ng-upload-change="uploadFile" my-id="$index">
</div>
</div>
It is better to write the directive without isolate scope.
app.directive('ngUploadChange', function() {
return{
/*
scope:{
ngUploadChange:"&",
myId:"="
},*/
link:function($scope, $element, $attrs){
$element.on("change",function(event){
var locals = { $event: event,
$id : $scope.$eval($attrs.myId)
};
$scope.$eval($attrs.ngUploadChange, locals);
});
/*
$scope.$on("$destroy",function(){
$element.off();
});*/
}
}
});
Use $scope.$eval instead of isolate scope bindings.
Isolate scope adds a scope and additional watchers which have been known to cause digest cycle delays that fight the ngModelController.
I am new in angularJS. Currently working on services. I tried to pass text-box value to services. I don't know how to pass. I code but it's not working.
app.service("wishService", function ($timeout) {
this.wishHim = function (_wishMessage) {
$timeout(function () {
alert('Hi ,' + _wishMessage);
}, 2000);
}
});
app.controller('wishCtrl', ['$scope', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);
<div ng-controller="wishCtrl">
Wish Message: <input type="text" ng-model="wishMessage" />
<input type="button" value="Send Message" ng-click="SendMessage(wishMessage)" /><br />
Your Message : {{Message}}
</div>
DEMO
wishService injection problem
app.controller('wishCtrl', ['$scope', 'wishService', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);
I fixed your code, see the PLUNK here. While what Sandeep said is correct, you also had a TON of other problems. Refer to what I changed.
Edit: It was brought to my attention that what I changed your code to is the format of a factory, rather than a service:
app.service("MessageService", function () {
var service = {
msg: undefined,
setMsg: function(msg){
this.msg = msg;
},
getMsg: function(msg){
return this.msg;
}
}
return service;
});
Basically I'm trying to pass the value of my dropbox to a get action.
The submit-button re-directs to the correct action , but what is the correct way to add the value of the dropbox with the re-direction?
My view:
#model TrackerModel
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Get, new { ???}))
{
<div>
<strong>#Html.LabelFor(m => m.CustomerName)</strong>
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #class = "customer-picker" })
</div>
<button class="styledbutton" onclick="window.location.href='/Tracker/Index'">Cancel</button>
<button type="submit" value="submit" id="selectCustomer-button" class="styledbutton">Submit</button>
}
[HttpGet]
public ActionResult MyAction(IPrincipal user, Tracker model)
Customer-picker
$(document).ready(function () {
CustomerPicker();
});
function CustomerPicker() {
$('.customer-picker').select2({
placeholder: 'Select customer',
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: '/JsonData/GetCustomers',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
query: term // search term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
formatResult: function (data) {
return data;
},
formatSelection: function (data) {
return data;
}
});
}
I was expecting the value to be within my Tracker model parameter in the action, but this returns nulls. Also I'm not sure what to place in the "new" parameter in the form tag?
I also tried the following but all I get returning to the controller is text:"".
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #id = "selectedCustomer", #class = "customer-picker" })
<script type="text/javascript">
$(function () {
$("#Form1").submit(function (e) {
alert("boo");
e.preventDefault();
var selectCustValue = $("#selectedCustomer").val();
$.ajax({
url: '/CalibrationViewer/SentMultipleCalsToCustomer',
data: { text: selectCustValue }
});
});
});
OK got it,
var selectCustValue = $("#s2id_CustomerName span").text();
Found another piece of code the used the customer-picker and the javascript associated with view used the above.
I viewed the page source and it still show's both id and name as CustomerName, it has something to do with the "Select 2" helper.
I may get slated for marking this as the answer, considering I should have figured it out earlier, but there you have it !