Why my push-method is not working using Ionic? - arrays

I am working with ionic 3 and I have problems with an alert controller when I try to push an element in mi array. I do not what is wrong with my code, I think that I only need to receive the parameters and push it to complete the action but I only get a big error when I try to execute my code.
I'm so sorry, I know that my English is so bad.
CODE
addPregunta() {
const prompt = this.alertCtrl.create({
title: "Login",
message: "Enter a name for this new album you're so keen on adding",
inputs: [
{
name: "title",
placeholder: "Title"
}
],
buttons: [
{
text: "Cancel",
handler: data => {
console.log("Cancel clicked");
}
},
{
text: "Save",
handler: data => {
const preObj = {
type: "radio",
label: data.title
};
this.preguntas.push(preObj);
this.changeData(data.title);
this.mermaidStart();
}
}
]
});
prompt.present();
}
ARRAY
preguntas: object[];
ERROR

preguntas: object[]; The preguntas property is defined but it's not initialised with a value.
console.log(this.preguntas) // will be undefined
The problem is in the save handler:
{
text: "Save",
handler: data => {
const preObj = {
type: "radio",
label: data.title
};
this.preguntas.push(preObj); // <-- the problem is with this line
this.changeData(data.title);
this.mermaidStart();
}
When this.preguntas.push(preObj) is called for the first time. this.preguntas is undefined, array.push will not work because this.preguntas is not an array.
The options you have are to initialise the preguntas property as an array, or check the value in the handler before your call .push.
Option 1
Initialise the property as an array
preguntas: object[] = [];
Option 2
Check the value in the save handler before pushing.
There are countless ways to check or even use an immutable approach
// similar style with your existing code
if(this.preguntas) {
this.preguntas.push(preObj);
} else {
this.preguntas = [preObj];
}
// immutable approach
this.preguntas = [...this.preguntas, preObj]

You have declared the variable as an Array type but you did not initialize it so fails when you are trying to push into it.

Related

React Double array statement UI

I want to show the comment array in the UI using the regid and the comment map. What should I do. Help
I have an array inside an array, so I don't know how to make it visible in the UI.
In case you have array inside an array, you will need two loops or two map statements to ensure that the same is returned. Below I have tried to take a similar object as yours to show how it should look like
// assuming you have below object
const obj = {
product: {
Comments: [
{
User: { regId: 1, content: "Comment 1 Content" }
},
{
User: { regId: 2, content: "Comment 2 Content" }
}
]
}
}
const renderComments = obj.product.Comments.map(({ User: { regId, content }) => <label>{regId}: {content});

How can I access all elements with a particular attribute in graphQL?

I have some json data in file called countryData.json structured as so:
{
"info":"success",
"stats":
[{
"id":"1",
"name":"USA",
"type":"WEST"
},
//...
I'm using graphQL to access this data. I have created an object type in the schema for countries using the following:
const CountryType = new GraphQLObjectType({
name: "Country",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
type: { type: GraphQLString },
})
});
I want to write a query that will allow me to access all of the elements of this array that have a certain "name" value(There can be multiple with the same name). I've written the following query, but it only returns the first match in the array:
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { type: { name: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
}
}
});
The "_" comes from const _ = require('lodash');
Also, how can I just get every single item in the array?
I have not recreated the code, therefore I can not check if it would be executed correctly. This is code, that should work in my opinion (without trying). If you want to return array of elements you need to implement https://lodash.com/docs/#filter. Filter will return all objects from stats, which match the argument name. This will return correctly inside resolver function, however, your schema needs adjustments to be able to return array of countries.
You need probably rewrite the arguments as follows as this is probably not correct. You can check out how queries or mutation arguments can be defined https://github.com/atherosai/express-graphql-demo/blob/feature/2-json-as-an-argument-for-graphql-mutations-and-queries/server/graphql/users/userMutations.js. I would rewrite it as follows to have argument "name"
args: { name: { type: GraphQLString } }
You need to add GraphQLList modifier, which defines, that you want to return array of CountryTypes from this query. The correct code should look something like this
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
},
countries: {
type: new GraphQLList(CountryType),
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.filter(countryData.stats, {name: args.name});
}
}
}
});
Now if you call query countries, you should be able to retrieve what you are expecting. I hope that it helps. If you need some further explanation, I made the article on implementing lists/arrays in GraphQL schema as I saw that many people struggle with similar issues. You can check it out here https://graphqlmastery.com/blog/graphql-list-how-to-use-arrays-in-graphql-schema
Edit: As for the question "how to retrieve every object". You can modify the code in resolver function in a way, that if the name argument is not specified you would not filter countries at all. This way you can have both cases in single query "countries".

Ionic 2 / 3: Number Input from Alert

I'm using Ionic 3.x on macOS.
I have the following issue:
I have an array containing a number and an array of names.
table: { number: number, names: string[] } = {
number: 0,
names: ['']
};
I want to set the number of the array using an input for the user. I stumbled upon the AlertController.
I have written the following function thing to add a number:
addTable(){
let prompt = this.alertCtrl.create({
title: 'Add Table',
subTitle: 'Enter the table number',
inputs: [{
name: 'tableNumber',
placeholder: 'Number',
type: 'number'
}],
buttons: [
{
text: 'Cancel'
},
{
text: 'Add',
handler: data => {
//this.tables.push(data);
this.table.number = data;
}
}
]
});
prompt.present();
}
But this always sets table.number to object [object]. If I write it as this.table.number = +data; it has the value NaN. The push version also doesn't work.
How do I set table.number to a number that the user put in?
The name of the input
name: 'tableNumber'
gets added as a property name to the resulting object. You can access it like this:
handler: data => {
this.table.number = data.tableNumber;
}

How can I Add and Delete nested Object in array in Angularjs

heres my output Image html How can I delete Object in array and push when adding some Data
angular.module('myApp.Tree_Service', [])
.factory('TreeService', function() {
var svc = {};
var treeDirectories = [
{
name: 'Project1',
id: "1",
type: 'folder',
collapse: true,
children: [
{
name: 'CSS',
id: "1-1",
type: 'folder',
collapse: false,
children: [
{
name: 'style1.css',
id: "1-1-1",
type: 'file'
},
{
name: 'style2.css',
id: "1-1-2",
type: 'file'
}
]
}
]
}
];
svc.add = function () {}
svc.delete = function (item, index) { }
svc.getItem = function () { return treeDirectories; }
return svc;
});
})();
I'm Newbee in Angularjs and I don't know how much to play it.
Hopefully someone can help me. Im Stucked.
Well you can delete any object by just usingdelete Objname.property
So for example you want to delete Children in treeDirectories first index object you can use delete treeDirectories[0].children if you want to delete children inside children then delete treeDirectories[0].children[0].children
if you want to remove an index from an array in lowest level children then
treeDirectories[0].children[0].children.splice(index,1)
for pushing data is for object you can directly assign value to the property you want
treeDirectories[0].children[0].newproperty = "check"
And for array you can
treeDirectories[0].children[0].children.push(object)

Custom Validate an object Push to an array

I am using something similar to the following schema.
By visiting the Item page I can add related items to the Item's Related Items array field.
I would like to custom validate the object I am pushing to the Item's Related Items field, to test if a similar object exists in the array already - so that I do not get a duplicate.
In my code below, the custom validation does not fire. I expect this may be because custom validation cannot be applied to a type: [object], and should be applied to the properties of the object - but then I am unable to test the object as a whole.
const ItemsSchema = new SimpleSchema({
name: {
type: String,
label: 'Name',
},
related: {
type: [Object],
label: 'Related Items',
optional:true,
custom: function () {
let queryData = { docId: this.docId, related: this.value }
if (Meteor.isClient && this.isSet) {
Meteor.call("relatedObjectIsUniqueForThisItem", queryData,
function (error, result) {
if(!result){
console.log("not unique");
return "Invalid";
}
else{
return true;
}
});
}
}
},
'related.$.name':{
type: String,
label:'Name',
},
'related.$.code':{
type:String,
label:'Code',
min:5,
},
});
I figured out the way to handle this.
The custom validation should not be on the [object], but rather one of the properties of the object - in this case 'source' or 'code'.
Inside one of the object properties you can call this.siblingField(otherField); But it means you have to rebuild the object.
In my case :-
const ItemsSchema = new SimpleSchema({
name: {
type: String,
label: 'Name',
},
related: {
type: [Object],
label: 'Related Items',
optional:true,
},
'related.$.name':{
type: String,
label:'Name',
custom: function () {
//---------------------------
//this is the important bit
//---------------------------
let queryData = {
docId: this.docId,
related: {
name:this.value,
code:this.siblingField('code').value,
}
}
//---------------------------
//end of important bit
//---------------------------
if (Meteor.isClient && this.isSet) {
Meteor.call("relatedObjectIsUniqueForThisItem", queryData,
function (error, result) {
if(!result){
console.log("not unique");
return "Invalid";
}
else{
return true;
}
});
}
}
},
'related.$.code':{
type:String,
label:'Code',
min:5,
},
});

Resources