AngularJS - using data from a service in a directive - json

I have set up a service to collect JSONP data from a server. If I use console.log to output 'data.d.results' in the service, I get a simple array object with six items.
However, when I do the same thing within the directive I get a much more complex object returned - one containing $$state, error, success, proto at the top level.
Because this is a more complex object, I can't figure out how to refer to the actual data that I'm after.
Can anybody tell me where I'm going wrong when passing the data or what I need to do to reference the data in the directive? When I go down the tree in the developer tools I find the actual data here:
d > $$state > value > data > d > results > [0-5] > CardID
My code is below:
app.directive('dashboardcard', ['DashboardCardService', function(DashboardCardService){
return{
restrict: 'E',
link: function($scope, element, atttributes){
$scope.data = DashboardCardService;
},
template: 'Card Name: {{CardID}}'
};
}]);
app.factory('DashboardCardService', ['$http', function($http){
var request = {
method: 'GET',
url: '/api.svc/tbl_Card/',
dataType: 'jsonp',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true
};
return $http(request).success(function(data) {
return data.d.results;
});
}]);
Thank you

One way to make it work with your current code and minimum changes would be something like that
app.directive('dashboardcard', ['DashboardCardService', function(DashboardCardService){
return{
restrict: 'E',
link: function($scope, element, atttributes){
DashboardCardService.success(function(data){
$scope.data = data
});
},
template: 'Card Name: {{CardID}}'
};
}]);
app.factory('DashboardCardService', ['$http', function($http){
var request = {
method: 'GET',
url: '/api.svc/tbl_Card/',
dataType: 'jsonp',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true
};
return $http(request)
}]);
or
app.directive('dashboardcard', ['DashboardCardService', function(DashboardCardService){
return{
restrict: 'E',
link: function($scope, element, atttributes){
$scope.dashboardService = DashboardCardService;
},
template: 'Card Name: {{dashboardService.data.CardID}}'
};
}]);
app.factory('DashboardCardService', ['$http', function($http){
var service = {};
var request = {
method: 'GET',
url: '/api.svc/tbl_Card/',
dataType: 'jsonp',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true
};
$http(request).success(function(data) {
service.data = data.d.results;
});
return service
}]);
You can also check my plunk that demonstrates several ways to put data into directive from service
http://plnkr.co/edit/YOzP2VCPOXwh4qoQC73i?p=preview

Related

Codes are displayed instead of html elements

I have called ajax request in some interval of time. Now, if I pressed the back button after success ajax then, the browser displayed all of my HTML code instead of displaying HTML elements.
<script>
window.setInterval(function () {
$.ajax({
method: 'GET',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '{{route('devices.index')}}',
dataType: 'json',
success: function (data) {
}
});
}, 1000);
</script>
if($request->ajax()){
foreach ($devices as $device){
$latestUpdate = Carbon::parse($device->updated_at);
$diff = Carbon::now()->diffInMinutes($latestUpdate);
if($diff > 2){
Device::where('id',$device->id)->update(['status'=>'3']);
}
}
return response()->json(['msg' => "successfully checked"]);
}
I had expected to render the HTML elements, but it displayed.
{
"msg": "successfully checked"
}
Same things happened when I send HTML in json.
if($request->ajax()){
$returnHtml = view('alerts.index', compact('threshold'))
->with('alerts', $alerts)->render();
return response()->json(['html' => $returnHtml, 'data' => $alerts]);
}
window.setInterval(function () {
$.ajax({
method: 'GET',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '{{route('alerts.index')}}',
dataType: 'json',
success: function (data) {
var formatedhtml = $('<div>').html(data.html).find('table');
$('table').html(formatedhtml);
}
});
}, 5000);
In this case it display
Instead of returning as json return data as array:
Try something like this
return ['html' => $returnHtml, 'data' => $alerts];
There's nothing wrong with how you are receiving the data when you use return response()->json(['html' => $returnHtml, 'data' => $alerts]);
If you want to actually put the html that you received from your server into an element in your page, you will need to use Element.innerHTML (https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) so that the html will not be escaped by the browser.
window.setInterval(function () {
$.ajax({
method: 'GET',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '{{route('devices.index')}}',
dataType: 'json',
success: function (data) {
// this is the table where you want to place the received table contents
var my_table=$('#my-table')
// we turn the data we received from the server into a jQuery object, then find the table we want data from
var received_table=$(data.html).find('table')
// switch out the table contents
my_table.html(received_table.html())
}
});
}, 1000);
EDIT: Since you are using jQuery, I changed the answer to fit.

AJAX success function not being called even though HTTP 200 is returned

When a user clicks 'buy now', I want the transaction to happen and the div to eventually be faded out and removed once being processed by the controller. Everything in the controller works as it should, but when I put the function in the success, it isn't called. However it works when the function is placed outside the success. Additionally, a window.alert() somehow works when there's a success.
Here is my script, everything works in regards to the controller etc
$(document).ready(function(){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('form.buy-product-form').on('submit', (function (e) {
e.preventDefault();
var product_id = $(this).attr("id");
$.ajax({
url: $(this).attr('action'),
type: 'POST',
data: {'id': product_id},
dataType: 'json',
success: function () {
window.alert("THIS ALERT COMMAND WORKS BUT THE FUNCTION DOESN'T!");
$(this).closest('.product').fadeOut("normal", function() {
$(this).closest('.product').remove();
});
}
});
}));
});
Everything above in the controller works fine as well, here is what it returns:
return response()->json(['ok' => 'ok']);
You cannot use this under success function because this is out scope . Just change your code like below :
$('form.buy-product-form').on('submit', (function (e) {
e.preventDefault();
var product_id = $(this).attr("id");
var element=this;//getting current element click in variable
$.ajax({
url: $(this).attr('action'),
type: 'POST',
data: {'id': product_id},
dataType: 'json',
success: function () {
window.alert("THIS ALERT COMMAND WORKS BUT THE FUNCTION DOESN'T!");
//passing variable
$(element).closest('.product').fadeOut("normal", function() {
$(element).closest('.product').remove();
});
}
});
}));

Adding Authorization to Header

i'm using Angular 6 and DevExpress Xtra-report module. I want to added Authorization in header.Well i'm using HttpInterceptor to add Authorization and its working good with all my others modules except my xtra-report module so i tried to pass the authorization using jquery inside my module (as shown bellow ) which is not working and i'm not really comfortable with it.
I'm getting the Token inside userId.
const userId = localStorage.getItem('access_token');
$.ajaxSetup({
cache: true,
type: 'POST',
xhrFields: {
withCredentials: true,
Authorization: `Bearer ${userId}`,
},
complete: function (result) {
// console.log('complete');
},
error: function (jqXHR, status, erreur) {
// console.log('error');
},
beforeSend: function (xhr, settings) {
console.log(`beforeSend beforeSend beforeSend beforeSend beforeSend beforeSend + ${userId}`);
xhr.withCredentials = true;
xhr.Authorization = `Bearer ${userId}`;
}
});
I dont know why HttpInterceptor work with all my module except xtra-report module, maybe cause i'm charging it lazy or i dont know , any help would be appreciated, tell me in case of additional informations from my side.
Thank you
i solved this by adding headers with Authorization inside it , so it becomes like this :
const userId = localStorage.getItem('access_token');
$.ajaxSetup({
cache: true,
type: 'POST',
xhrFields: {
withCredentials: true,
},
headers: {
Authorization: `Bearer ${userId}`,
},
complete: function (result) {
// console.log('complete');
},
error: function (jqXHR, status, erreur) {
// console.log('error');
},
beforeSend: function (xhr, settings) {
console.log(`beforeSend beforeSend beforeSend beforeSend beforeSend beforeSend + ${userId}`);
xhr.withCredentials = true;
xhr.Authorization = `Bearer ${userId}`;
}
});
Hopefully this could help someone one day

no display fail message from controller

I need validate user's nickname when the gonna registre in my proyect:
My Controller
$inputData = Input::get('nickname');
parse_str($inputData);
$informacion = array('nickname' => $inputData);
$regla = array('nickname'=>'required|unique:usuarios|alpha_num|min:6|max:15');
if($request->ajax()){
$usuarios = Usuarios::Usuarios();
$validar = Validator::make($informacion,$regla);
if($validar->fails()){
return Response()->json(array(
'fail' => true,
'errors' => $validar->getMessageBag()->toArray()));
}
else{
return Response()->json(array('success' => true, "message" => "Nombre de Usuario Disponible"));
}
}
My Script
$( "#validar" ).click(function( event ) {
var dato = $('#nickname').val();
var route = $('#form-sign-up').attr('action');
var tipo = $('#form-sign-up').attr('method');
var token = $('#form-sign-up #token').val();
$.ajax({
url: route,
headers: {'X-CSRF-TOKEN': token},
type: tipo,
dataType: 'json',
data:{nickname: dato},})
.fail(function(data){
$('#nickname-msj').html(data.errors);
$('#nickname-msj').fadeIn();
})
.done(function(data) {
$('#nickname-msj').html(data.message);
$('#nickname-msj').fadeIn();
});
});
.done works, but .fails not, and i need display that information to my user, because so they can know what is the problem, if someone can help me will be great.
I am using Laravel 5.2
Thank you.
The fails function of Ajax is triggered with a code different from 200. So you can return
if($validar->fails()) {
return response()->json($arrayHere, 400); //HTTP 400 error for bad request
}
So, just basically add 400 after your array, inside of json() function. When you don't specify the code, it defaults to 200.
Maybe also change your ajax request ? Or not
$.ajax({
url: route,
headers: {'X-CSRF-TOKEN': token},
type: tipo,
dataType: 'json',
data:{
nickname: dato
},
success: function (data) {
console.log(data);
},
error: function (data) {
console.log('Error:', data);
}
});

why it's appending #/... in location.hash

I am using angular js for my app.
Here , My Angular code as :
var app = angular.module('TaskManager', ['ngCookies']);
app.controller('LoginController', function($scope, $http, $location, $cookieStore) {
$scope.login = function(str) {
console.log(".......... login called......");
$http({
method: 'POST',
url: '../TaskManager/public/user/login',
data: $.param({
email: email.value,
password: password.value
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(data, status) {
console.log(data);
var result = data.response;
console.log(result);
if (result == "success") {
//storing value at cookieStore
$cookieStore.put("loggedin", "true");
$cookieStore.put("loggedUserId", data.user_id);
$cookieStore.put("password", data.password);
$cookieStore.put("type", data.type);
$cookieStore.put("email", data.email);
location.href='Dashboard.html';
} else alert(data.message);
});
});
app.controller('DashboardController', function($scope, $http, $location, $cookieStore) {
$scope.users = [];
$http({
method: 'POST',
url: '../TaskManager/public/task/tasklist',
data: $.param({
logged_userid: userId,
password: password,
status: 'All',
user_id: useridToFetch
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(data, status) {
console.log(data);
$scope.users = data.users;
});
//location.hash="";
console.log(window.location);
});
It works fine but when it redirects to the dashboard page after logged in, the location.hash is being assigned with the #/PAGE_NAME. it becomes location.hash=#/PAGE_NAMEwhich results the URL value repetition.
Like:
http://localhost:8085/NovaTaskManager/Dashboard.html#/Dashboard.html
I tried to clear hash at DashboardController, Which clears for a while but as soon as the page is refreshed the earlier URL appears again.
Don't know:
1. why location.hash is getting assigned by default ?
2. How it can be resolved ?
Any suggestion would be appreciated.