I'm trying to build my first Ionic app and to use a simple list population using $http.get and JSON. What I have is this:
.controller('ReportTabCtrl', function($scope) {
$scope.items = [
{ id: 0 },
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 9 },
{ id: 10 },
{ id: 11 },
{ id: 12 },
{ id: 13 },
{ id: 14 },
{ id: 15 },
{ id: 16 },
{ id: 17 },
{ id: 18 },
{ id: 19 },
{ id: 20 },
{ id: 21 },
{ id: 22 },
{ id: 23 },
{ id: 24 },
{ id: 25 },
{ id: 26 },
{ id: 27 },
{ id: 28 },
{ id: 29 },
{ id: 30 },
{ id: 31 },
{ id: 32 },
{ id: 33 },
{ id: 34 },
{ id: 35 },
{ id: 36 },
{ id: 37 },
{ id: 38 },
{ id: 39 },
{ id: 40 },
{ id: 41 },
{ id: 42 },
{ id: 43 },
{ id: 44 },
{ id: 45 },
{ id: 46 },
{ id: 47 },
{ id: 48 },
{ id: 49 },
{ id: 50 }
];
});
And this works great. The list is populated as it should. What I want is to move the contents of $scope.items to an external file (to be able to generate it dynamically) and call it using $http.get.
I've tried this without any success:
.controller('ReportTabCtrl', function($scope, $http) {
$http.get('items.json')
.success(function(data) {
$scope.items = data;
})
});
The content of the items.json file is the same as the $scope.items variable.
What am I doing wrong?
/Carl
You need to put " double qoutes aside id property in each element of items.json to make it valid json
items.json
[
{ "id": 0 },
{ "id": 1 },
{ "id": 2 }
// and so on
//.
//.
]
Demo Plunkr
I would also read this previous thread AngularJS: factory $http.get JSON file.
There are a couple things that could be going wrong for you.
Related
I have this json in MongoDB:
{
_id: ObjectId("630fbb09cc9deb16a33fbcde"),
firmness: {
name: 'hard',
url: 'https://pokeapi.co/api/v2/berry-firmness/3/'
},
flavors: [
{
flavor: {
name: 'spicy',
url: 'https://pokeapi.co/api/v2/berry-flavor/1/'
},
potency: 10
},
{
flavor: {
name: 'dry',
url: 'https://pokeapi.co/api/v2/berry-flavor/2/'
},
potency: 0
},
{
flavor: {
name: 'sweet',
url: 'https://pokeapi.co/api/v2/berry-flavor/3/'
},
potency: 0
},
{
flavor: {
name: 'bitter',
url: 'https://pokeapi.co/api/v2/berry-flavor/4/'
},
potency: 0
},
{
flavor: {
name: 'sour',
url: 'https://pokeapi.co/api/v2/berry-flavor/5/'
},
potency: 10
}
],
growth_time: 2,
id: 20,
item: { name: 'pinap-berry', url: 'https://pokeapi.co/api/v2/item/145/' },
max_harvest: 10,
name: 'pinap',
natural_gift_power: 70,
natural_gift_type: { name: 'grass', url: 'https://pokeapi.co/api/v2/type/12/' },
size: 80,
smoothness: 20,
soil_dryness: 35
}
And I want to get the soil_dryness field and the field called "name" into flavor list from 'flavors' array.
How can I do that?
I tried with:
db.Berries.find({},{soil_dryness:1},{"flavors.$":1}).pretty().limit(20)
But unfortunately doesn't works.
Query
project, the soil_dryness and the names, path in arrays = array with the values, here the names
*not sure if this the output you need, if its not if you can add the expected ouput you need
Playmongo
db.Berries.aggregate(
[{"$project": {"soil_dryness": 1, "names": "$flavors.flavor.name"}},
{"$limit": 20}])
I have one list look like allsettings. I want to convert that list to a new list. Since I am new to react I don't have much idea, I tried by doing the below way but 1st item in the new list is always empty.
const [mySetting, setMySet] = useState([]);
useEffect(() => {
const allSettings = [
{ name: "Setting1", value: true, label: 1 },
{ name: "Setting2", value: true, label: 2 },
{ name: "Setting3", value: true, label: 3 },
{ name: "Setting4", value: false, label: 4 },
{ name: "Setting5", value: true, label: 5 },
{ name: "Setting6", value: true, label: 6 },
{ name: "Setting7", value: true, label: 7 }
];
const settings = [];
const allSettingsMap = allSettings.reduce((resMap, current) => {
settings.push(resMap);
return {
...resMap,
SettingID: current.label,
Name: current.name,
value: current.value
};
}, {});
setMySet(settings);
}, []);
//I want new list like this:
const newSettings = [
{ name: "Setting1", value: true, SettingID: 1 },
{ name: "Setting2", value: true, SettingID: 2 },
{ name: "Setting3", value: true, SettingID: 3 },
{ name: "Setting4", value: false, SettingID: 4 },
{ name: "Setting5", value: true, SettingID: 5 },
{ name: "Setting6", value: true, SettingID: 6 },
{ name: "Setting7", value: true, SettingID: 7 }
];
You can use array#map to rename a key in your object and keeping other keys intact. For each object, you can pick label and rename it to SettingID and keep other key-values same.
const allSettings = [ { name: "Setting1", value: true, label: 1 }, { name: "Setting2", value: true, label: 2 }, { name: "Setting3", value: true, label: 3 }, { name: "Setting4", value: false, label: 4 }, { name: "Setting5", value: true, label: 5 }, { name: "Setting6", value: true, label: 6 }, { name: "Setting7", value: true, label: 7 } ],
result = allSettings.map(({label, ...other}) => ({...other, SettingID: label}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can easily do it by map on array
const allSettings = [
{ name: "Setting1", value: true, label: 1 },
{ name: "Setting2", value: true, label: 2 },
{ name: "Setting3", value: true, label: 3 },
{ name: "Setting4", value: false, label: 4 },
{ name: "Setting5", value: true, label: 5 },
{ name: "Setting6", value: true, label: 6 },
{ name: "Setting7", value: true, label: 7 }
];
const newAllSettings = allSettings.map(item => {
return {
name: item.name,
value: item.value,
SettingID:item.label
};
});
console.log(newAllSettings)
Replace your allSettings.reduce method with this map method
const settings = [];
allSettings.map((setting) => {
const item = { ...setting };
const tempValue = item?.label;
// delete item label
delete item["label"];
item["SettingID"] = tempValue;
settings.push(item);
});
I have two layout scenarios and one set of data. This is the original data:
var shape = [
{ name: "fruit", value: 'apple' },
{ name: "fruit", value: 'orange' },
{ name: "rootVegetable", value: 'turnip' },
{ name: "rootVegetable", value: 'carrot' },
{ name: "vegetable", value: 'cabbage' },
{ name: "vegetable", value: 'potato' }
];
And here’s how I would like it to look:
var shape2 = [
[
{ name: "fruit", value: 'apple' },
{ name: "rootVegetable", value: 'turnip' },
{ name: "vegetable", value: 'cabbage' },
],
[
{ name: "fruit", value: 'orange' },
{ name: "rootVegetable", value: 'carrot' },
{ name: "vegetable", value: 'potato' },
]
]
Then I could render a table from that:
| Fruit | Root vegetable | Vegetables |
| ------ | -------------- | ---------- |
| apple | turnip | cabbage |
| orange | carrot | potato |
I know this a case for reduce but I can’t quite figure it out.
You can try this.
var shape = [
{ name: "fruit", value: 'apple' },
{ name: "fruit", value: 'orange' },
{ name: "rootVegetable", value: 'turnip' },
{ name: "rootVegetable", value: 'carrot' },
{ name: "vegetable", value: 'cabbage' },
{ name: "vegetable", value: 'potato' }
];
function getResult(shape) {
var fruits = [];
var rootVegetable = [];
var vegetable = [];
var result = [];
shape.forEach(s => {
if (s.name == "fruit")
fruits.push(s);
else if (s.name == "rootVegetable")
rootVegetable.push(s);
else if (s.name == "vegetable")
vegetable.push(s);
})
fruits.forEach((item, idx) => {
var smallArray = [];
smallArray.push(item)
smallArray.push(rootVegetable[idx]);
smallArray.push(vegetable[idx]);
result.push(smallArray);
})
return result;
}
console.log(getResult(shape));
I have a computed property witch looks inside a items: {} array, this array have 26 objects inside. The property only "read" the first 23 objects, the 24 and the next ones looks out of the filter range.
Before this conclusion i think the problem is because the 24 object have an special character but i revert the array order and the special character was filter correctly.
items: [
{...},
23: {
alias: "Correcto",
id: 11
},
24: {
alias: "Tamaño",
id: 12
}
25: {
alias: "silla",
id: 13
]
};
This is the code of my filter as a computed: porperty
computed: {
filteredItems() {
if (this.items) {
return this.items.filter((item) => {
if (!this.search) return '';
return item.alias.toLowerCase().match(this.search.toLowerCase().trim());
});
}
}
},
How can i make the filter works with big arrays?
Array's filter method does not has a limitation, the problem here it's the .match() method which check by regex, replace it with .includes() which search if the string passed as parameter occours in the desired string.
.includes() Docs MDN
Little example emulating "large" data
new Vue({
el: '#example',
computed: {
filteredItems () {
return this.items.filter(i => i.alias.toLowerCase().includes(this.filterText.toLowerCase()))
}
},
data () {
return {
filterText: '',
items: [
{
alias: "it\'s working",
id: 1
},
{
alias: "lool",
id: 2
},
{
alias: "vue is awesome",
id: 3
},
{
alias: "another text",
id: 4
},
{
alias: "some value",
id: 5
},
{
alias: "teest",
id: 6
},
{
alias: "bar",
id: 7
},
{
alias: "foo",
id: 8
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
},
{
alias: "silla",
id: 9
},
{
alias: "Corrécto",
id: 10
},
{
alias: "Tamaño",
id: 11
},
{
alias: "ñoo",
id: 12
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>
<div id="example">
<input type="text" v-model="filterText" />
<ul>
<li v-for="item in filteredItems">{{ item.alias }}</li>
</ul>
</div>
If you mean that you can't get a match when searching strings with characters outside of a-Z range. A basic solution could be to use js charCodeAt function that converts characters to UTF-16 codes. Below is a basic example:
function encodeString(str) {
return str.split('').map(letter => letter.charCodeAt(0)).join('~'); // ~ is to split chars and not to let one mix with other acidentally
}
so your code might actually look something like this:
...
computed: {
filteredItems() {
if (this.items) {
return this.items.filter(item => {
if (!this.search) return false;
return this.isMatching(item.alias, this.search);
});
}
}
},
methods: {
...
encodeString(str) {
return str.split('').map(letter => letter.charCodeAt(0)).join('~');
},
isMatching(haystack, keyword) {
haystack = haystack.toLowerCase().trim();
keyword = keyword.toLowerCase().trim();
return this.encodeString(haystack).match(this.encodeString(keyword));
},
...
}
...
i build a list using .factory and in every elemt have a arrtibute which store page which needed to be include when clicked on any list item
.
i am unable to use this attribute dynamiclly ..plzz help,,,,
i am using ionic framework
////////////// service.js ////////////////
angular.module('starter.services', [])
.factory('Ctopic', function() {
// Might use a resource here that returns a JSON array
// Some fake testing data
var chats = [ { title: 'Arrays', id:11 ,desc: "'ctopic/Union.html'"},
{ title: 'Bit Field Declaration', id:12 },
{ title: 'C Pointers', id: 13 },
{ title: 'Conditional Statements', id: 14 },
{ title: 'File IO', id: 15 },
{ title: 'Function', id: 16 },
{ title: 'Input & Output', id: 17 },
{ title: 'Loops', id: 18 },
{ title: 'Preprocessor Operators', id: 19 },
{ title: 'Preprocessor', id: 20 },
{ title: 'String', id: 21 },
{ title: 'Structures', id: 22 },
{ title: 'Typedef', id: 23 },
{ title: 'Union', id: 24 }];
return {
all: function() {
return chats;
},
remove: function(chat) {
chats.splice(chats.indexOf(chat), 1);
},
get: function(chatId) {
for (var i = 0; i < chats.length; i++) {
if (chats[i].id === parseInt(chatId)) {
return chats[i];
}
}
return null;
}
};
});
/////// html page /////////
<ion-view view-title="{{chat.title}}">
<ion-content class="padding">
{{chat.id}}
{{chat.desc}}
<div ng-include="{{chat.desc}}"></div>
</ion-content>
</ion-view>
Don't use the brackets for ng-include:
<div ng-include="chat.desc"></div>