Using ng-repeat on a string that contain a json - javascript

i have this situation: i want to use ng-repeat directive on a String that contains Json line. This string come from a rest service with jersey. When i call the page that contains this directive there is an error. How i can resolve this situation? Thanks to all.
SyntaxError: Unexpected token {
at Object.parse (native)
at fromJson (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:1035:14)
at defaults.defaults.transformResponse (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:6933:18)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:6908:12
at Array.forEach (native)
at forEach (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:302:11)
at transformData (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:6907:3)
at transformResponse (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:7589:17)
at deferred.promise.then.wrappedCallback (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:10943:81)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js:11029:26
}
This is my code:
list.html
<tr ng-repeat="person in persons">
<td>{{ person.name }}</td>
<td>{{ person.lastname }}</td>
<td>{{ person.tasks }}</td>
<td>{{ person.skills }}</td>
<td><a ng-click="editUser(person.id)" class="btn btn-small btn-primary">Modifica</a></td>
<td><a ng-click="deleteUser(person.id)" class="btn btn-small btn-danger">Elimina</a></td>
</tr>
services.js
services.factory('PersoneFactory', function ($resource) {
return $resource(baseUrl + '/GestRisorse/rest/person/personList', {}, {
query: { method: 'GET', isArray: false },
})
});
controller.js
app.controller('PersonListCtrl', ['$scope', 'PersoneFactory', 'PersonFactory', '$location',
function ($scope, PersoneFactory, PersonFactory, $location) {
$scope.persons = PersoneFactory.query();
}]);
restController.java
#Path("/person")
public class PersonRestController {
private PersonDAO personDao = new PersonDAO();
#GET
#Path("/personList")
#Produces("application/json")
public String getPersonList() {
return personDao.getAllPerson();
}
...
}
personDao.java
public String getAllPerson(){
DBCollection collection = connection.getCollection("users");
StringBuffer s = new StringBuffer();
DBCursor cursor = collection.find();
try {
while(cursor.hasNext()) {
s.append(cursor.next());
}
} finally {
cursor.close();
}
return s.toString();
}
...
}

Thanks to the people that wrote comment under my question, i want to say them that I found the problems, there where 2:
1) i didnt use properly the promise, now i add in the controller these line
PersoneFactory.query().$promise.then(function(data) { $scope.persons = JSON.parse(data); }, function(errResponse) { console.log("errore"); });
2) i didnt format json properly, so the string that came from backend wasn't a valid json.
Thanks to all.

Related

Is there a way of displaying the value of an object inside an array?

I'm building a component on my project, which is actually getting all the data and console logging it, but here's the problem: Inside my array of clients, i have some objects (address, documents, ...), and i can't manage to call them on my table.
My script:
<script>
export default {
data: () => ({
clients: [],
}),
methods: {
getClients() {
this.$api
.get("/api_v1/clientes", {
})
.then((response) => {
this.clients = response.data[0];
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
},
mounted() {
this.getClients();
},
};
</script>
My table (inside ):
<tbody>
<tr v-for="client in clients" v-bind:key="client.id">
<td>{{ client.id }}</td>
<td>{{ client.name }}</td>
<td>{{ client.email }}</td>
<td>{{ client.documents.cpf || client.documents.cnpj }}</td>
<td>{{ client.documents.celular }}</td>
<td>{{ client.status }}</td>
<td v-if="client.address">
{{ `${client.address.localidade} / ${client.address.uf}` }}
</td>
<td v-else>-</td>
<td>
<a :href="`/see-client/${client.id}`"
><i class="icon-magnifier"></i
></a>
<i class="icon-check" style="color: green"></i>
<i class="icon-close" style="color: red"></i>
</td>
</tr>
</tbody>
My controller:
public function index(Request $request)
{
$data = [
'pag' => 'All clients',
'link' => '/'
];
return view('clients.index', $data);
}
The data:
Someone have a clue of a different approach i could have? I'm using Vue2. It's one of my first big projects, so previously sorry for any rookie mistake. Thanks for your time and help!
This line is only getting the first client:
this.clients = response.data[0];
response.data is your array of clients (from the looks of things). When you use .data[0], you're getting the first element of the array (i.e. the first client).
Then, this line is trying to loop over 1 client, not an array of clients.
<tr v-for="client in clients" v-bind:key="client.id">
Try changing
this.clients = response.data[0];
to
this.clients = response.data;
If that doesn't work (it looks like you've got a weird data structure), try this instead:
this.clients = response.data.data;
Or this (it's unclear to me how many nested data properties you have):
this.clients = response.data.data.data;
I just made a quick analysis about your code. I think you should polish it a little bit.
Let me start with a quick catch up:
Update yuor js section with:
<script>
export default {
// Please do use the function format instead of lambda expression, it's recommended in the vue2 docs.
data() {
return {
clients: [],
};
},
methods: {
// Change this to an async method, so you can have more control on your code.
async getClients() {
try {
/**
* Here, you should have to know, that your file `routes/api.php` hass all of the prefixed /api routes
* So you have a direct access to /api prefixed routes
* Additionally read a little bit about destructuring.
*/
const response = await this.$api.get("/api/clientes");
// Now, please notice that you have 2 data path names.
this.clients = response.data.data; // {or please follow the correct path to the array container of the clients}.
} catch (e) {
console.log("Check this error: ", e);
}
},
},
// Now, change your mounted to an async method
async mounted() {
// Trust me this is going to work perfectly.
await this.getClients();
},
};
</script>
Now, please, please change your api controller logic to a response()->json(...)
public function index(Request $request)
{
// Your retrieve logic...
return response()->json($data);
}
Finally if you have successfully configured everything abouve, your vue component should be able to retrieve the information correctly, and your tbody must work this way...
<tbody>
<tr v-for="client in clients" v-bind:key="client.id">
<td>{{ client.id }}</td>
<td>{{ client.name }}</td>
<td>{{ client.email }}</td>
<td>{{ client.documents.cpf || client.documents.cnpj }}</td>
<td>{{ client.documents.celular }}</td>
<td>{{ client.status }}</td>
<td v-if="client.address">
<!-- You can replace what you have with: -->
{{ client.address.localidade }} / {{ client.address.uf }}
</td>
<td v-else>
-
</td>
<td>
<a :href="`/see-client/${client.id}`">
<i class="icon-magnifier"></i>
</a>
<i class="icon-check" style="color: green"></i>
<i class="icon-close" style="color: red"></i>
</td>
</tr>
</tbody>

How to create load more in search result with vue js and laravel

I want to create function load more in my search result with vue js and laravel.
This is what I try.
My form code to search
<form #submit.prevent="search">
<input v-model="term" type="search">
<button class="btn btn-success" type="submit">Search</button>
</form>
here is to show search result
<tr v-for="(result, index) in results.data">
<td>{{ result.artist_name }}</td>
<td>{{ result.gender }}</td>
<td>{{ result.created_at }}</td>
<td>{{ result.updated_at }}</td>
</tr>
<div v-if="results.next_page_url" class="card-footer">
<button #click.prevent="paginatesearch(results.next_page_url)" type="button">Load More</button>
</div>
here is my data variable
data() {
return {
term:'',
results:[],
}
},
Here is my code to showing search result.
search() {
let formData = new FormData();
formData.append('term', this.term);
axios.post('/api/artist/search/', formData)
.then((response) => {
this.SearchDiv = true;
this.IndexDiv = false;
this.results = response.data;
this.noResults = this.results.length === 0;
});
},
and this is my code to show load more data
paginatesearch(url = '') {
this.loading = true;
this.disabled = 1;
axios.get(url ? url : '/api/artist/search/')
.then(response => {
this.loading = false;
this.disabled = 0;
if (! this.results.data) {
this.results = response.data
}
else {
this.results.data.push(...response.data.data)
this.results.next_page_url = response.data.next_page_url
}
})
.catch(e => console.error(e))
},
But when I click the button, it give me
TypeError: Cannot convert undefined or null to object
Here is my full code if u need it https://github.com/jazuly1/nginx/blob/master/loadmorewithsearch.vue
'results'is defined as an array, but is used as an object.
just need a simple correction..
in search method change axios.post('/api/artist/search/', formData) to axios.post('/api/artist/search/' + this.$data.term)
and in paginatesearch method change axios.get to axios.post.
and some correction in controller page. now everything is working fine.

Using Angular ES5 to create filters

I've created a project using Angular v 4.4.4 in ES5 and I'm having difficulties making a pipe filter to filter table results (*ngFor is used to populate the table). Ive searched all over and was not able to find an example. is this possible to do and if so can someone provide me with an example?
Here is my incomplete code attempt so far
var SearchFilter = ng.core
.Pipe({
name: "searchFilterTable"
})
.Class({
constructor: function SearchFilter () {},
transform: function() {
}
});
Found a solution:
ES5
var SearchFilter = ng.core.Pipe({
name: "searchFilterTable"
})
.Class({
constructor: function SearchFilter () {},
transform: function(elements, string) {
console.log(elements);
console.log(string);
return elements.filter(
item => item.name.toLowerCase().indexOf(string.toLowerCase()) !== -1);
}
});
Html
<tr *ngFor='let gateway of gateways | searchFilterTable:keyword'>
<td class="special-td">{{ gateway.name }}<br><a>(edit)</a></td>
<td class="special-td">{{ gateway.type }}</td>
<td class="special-td">{{ gateway.forwardingAddress }}</td>
<td class="special-td copy">{{ gateway.key }}</td>
<td class="special-td"></td>
</tr>
Make sure to add the Pipe into your declarations/imports

Concat 2 datas from json Angular ng-repeat

I try to put data from another array into one part in table.
My first json "names" :
[
{
"name": "AAAAAA",
"down": "False"
},
{
"name": "BBBBBB",
"down": "True"
},
{
"name": "CCCCC",
"down": "False"
}
]
Second json "data" :
[
{
"data": "35%"
}
]
Javascript:
var app = angular.module('app', []);
app.service('service', function($http, $q){
this.getNames = function () {
var names = $http.get('names.json', {cache: false});
var datas = $http.get('data.json', {cache: false});
return $q.all({datas,names});
};
});
app.controller('FirstCtrl', function($scope, service, $http) {
var promise = service.getNames();
promise.then(function (data) {
$scope.names = data.names.data;
$scope.datas = data.datas.data;
$scope.namesanddata = $scope.names.concat($scope.datas);
console.log($scope.namesplit);
console.log($scope.datas);
});
});
Table in HTML :
div ng-controller="FirstCtrl"
<table>
<tbody>
<tr ng-repeat="name in namesanddata">
<td>{{name.name}}</td>
<td ng-if="name.down=== 'False'">{{name.down}}</td>
<td ng-if="name.down !== 'False'">{{name.data}}</td>
</tr>
</tbody>
</table>
</div>
My problem - <td ng-if="name.down !== 'False'">{{name.data}}</td>dont show in table. in console.log it concat to array like 4 object and probably by this it don't show in table next to {{name.name}}, but i don't know how to show {{name.data}} from another json in table instead {{name.down}}.
Thanks for answers in advance.
To give you an output of:
AAAAAA False
BBBBBB 35%
CCCCC False
Remove this line from the Controller:
$scope.namesanddata = $scope.names.concat($scope.datas);
Then either:
Solution 1 - Inline in the view
Change your ng-repeat as follows:
<tr ng-repeat="name in names">
<td>{{ name.name }}</td>
<td>{{ (name.down === 'False') ? name.down : datas[0].data }}</td>
</tr>
OR
Solution 2 - Keep the view clean by using a Filter
app.filter('myFilter', function () {
return function(items, datas) {
var filtered = [];
angular.forEach(items, function (i) {
if (i.down !== "False")
i.down = datas[0].data;
filtered.push(i);
});
return filtered;
}
});
Change your ng-repeat as follows:
<tr ng-repeat="name in names | myFilter: datas">
<td>{{ name.name }}</td>
<td>{{ name.down }}</td>
</tr>

How to get result data in Angular promise request?

I am studying Angular and I have a problem with my code. I am trying to create an ajax request by using promise and service. My output in ajax access in successful but I can't display it in the view.
Here's some of my code:
<div ng-app="promiseCall">
<div ng-controller="promiseCtrl">
<button tyle="button" class="btn btn-default" ng-click="promiseCallRequest()">Promise Call</button>
<table class="table table-bordered table-hovered">
<thead>
<tr>
<td class="text-center"><label>ID</label></td>
<td class="text-center"><label>TITLE</label></td>
<td class="text-center"><label>BODY</label></td>
<td class="text-center"><label>CREATED AT</label></td>
<td class="text-center"><label>UPDATED AT</label></td>
</tr>
</thead>
<tbody>
<!-- no output -->
<tr ng-repeat="item in noteListing">
<td>{{ item.id }}</td>
<td>{{ item.title }}</td>
<td>{{ item.body }}</td>
<td>{{ item.created_at }}</td>
<td>{{ item.updated_at }}</td>
</tr>
</tbody>
</table>
</div>
</div>
angular.module('promiseCall',[])
.controller('promiseCtrl', function($scope, $log, noteData) {
$scope.promiseCallRequest = function() {
var getPromiseCallData = noteData.getNoteData();
getPromiseCallData.then({
function(payload) {
console.log(payload); //no output :(
//$scope.noteListing = payload.data;
},
function(errorPayload) {
$log.error('Failure request in note', errorPayload);
}
});
}
}).factory('noteData', function($http, $log, $q) {
return {
getNoteData: function() {
var deferred = $q.defer();
$http.get("<?php echo site_url('tutorial/getAjaxData'); ?>")
.success(function(data){
/*
deferred.resolve({
id: data.id,
title: data.title
});
*/
//console.log('success'); -- ok
})
.error(function(msg, code){
deferred.reject(msg);
$log.error(msg, code);
alert('there must be an error!');
});
return deferred.promise;
}
}
});
Here's the JSON output:
{"article_data":[{"id":"1","title":"sample updated 1","body":"sample 1","created_at":"2015-06-15 15:37
:28","updated_at":"2015-06-15 21:38:46"},{"id":"2","title":"sample 2","body":"sample 2","created_at"
:"2015-06-15 15:37:54","updated_at":"2015-06-15 15:37:54"}]}
Try to remove the {} in your getPromiseCallData.then({});.
E.g.
$scope.promiseCallRequest = function() {
var getPromiseCallData = noteData.getNoteData();
getPromiseCallData.then(
function(payload) {
console.log(payload); //no output :(
//$scope.noteListing = payload.data;
},
function(errorPayload) {
$log.error('Failure request in note', errorPayload);
}
);
};
Hope it helps.
try the below code:
....
getPromiseCallData.then(function(payload) {
console.log(payload); //no output :(
//$scope.noteListing = payload.data;
}).catch(function(errorPayload) {
$log.error('Failure request in note', errorPayload);
});
...
getNoteData: function() {
return $http.get("<?php echo site_url('tutorial/getAjaxData'); ?>");
}
in getNoteData, what you did was a promise anti-pattern, you already have a promise, no need to create another wrapper for it.
Edit:
if you want to log the service's success and error, you could simply do, you still don't need an additional promise:
getNoteData: function() {
return $http.get("<?php echo site_url('tutorial/getAjaxData'); ?>").then(function(data){
//some log
return data;
}, function(err){
// log err
return err;
});
}

Categories

Resources