Simple but useful problem of context

telerikuicomponent
nativescriptcore

#1

when i run this on loaded …

viewModel.selectedContactForEstimate = function(){
    console.log("inside select...");
    var context = page.navigationContext;
    console.log(context);
    viewModel.set("contactList",context);
}

i ll get these things in console

  inside select...

{
“_id”: “5b446166b80d61190432d879”,
“title”: "Mrs. ",
“selectedTitleIndex”: 1,
“firstname”: “Sakshi”,
“phone”: “8976755948”,
“lastname”: “Shivanand”,
“email”: “da jauajajb@gmail.com”,
“gstn”: “Dbsj46”,
“adl1”: "Bangalore ",
“state”: “Karnataka”,
“city”: “Bangalore”,
“adl2”: “Bangalore”,
“selectedStateIndex”: 10,
“pincode”: “569040”,
“imageRefId”: “”,
“_acl”: {
“creator”: “5b31c86a755ccb4b137a35be”
}
}

but when i try to print only one value like

  console.log(context.firstname); 
          or console.log(context['firstname']); 
          or console.log(context[1]);

im getting error “cannot read property firstname of undefined” why i dont know please clarify this simple issue

so context is not an array please tell me what is it. and how to access its elements.
no where in document or here i found a solution. if there is an existing thread please give link of that…

    viewModel.set("contactList",context);
}

#2

navigationContext could be whatever you pass to context in NavigationEntry.

It sounds really strange, when it prints for you in console but throws error when you access it. Can you try creating a playground example where we can reproduce the issue - a complete code may help to crack what exactly happening here.


#3

u can recreate it in simple steps.

just read all data from kinvey database. dont use any other database.
sample code is here which ull get on kinvey website for nativescript - data

var dataStore = Kinvey.DataStore.collection(‘contacts’);
const query = new Kinvey.Query();
query.fields = [’_id’, ‘title’, ‘selectedTitleIndex’, ‘firstname’, ‘lastname’, ‘phone’, ‘email’, ‘shopname’, ‘gstn’, ‘imageRefId’, ‘adl1’, ‘adl2’, ‘state’, ‘selectedStateIndex’, ‘city’, ‘pincode’];
const subscription = dataStore.find(query)
.subscribe(function (entities) {
viewModel.set(“contactList”, entities);
}, function (error) {
console.log(error);
}, function () {

        });

here also u cannot print single data from entities, but u can list it in xml using listview or radlistview.
and recreate the issue in pure javascript please…


#4

First, I don’t have a Kinvey account / setup. Secondly you mentioned that the problem seems to be with navigationContext. So without a complete working example, I may not be able to debug this.


#5

i found that only when i read data from database then such entities will behave like that.
if i try to print any one content of entity it will give undefined result. i just want to know why this error…

important: add npm pakage kinvey-nativescript-sdk on playground

app.js

var application = require(“application”);
var Kinvey = require(‘kinvey-nativescript-sdk’).Kinvey;

Kinvey.init({
appKey: ‘kid_SJ_cPrkfX’,
appSecret: ‘598ba806133f4aaa9dd3e1eb90f13f25’
});

var promise = Kinvey.User.logout().then(function (user) {
console.log(“logout successfull…”);
Kinvey.ping()
.then(function (response) {
console.log('Kinvey Ping Success. Kinvey Service is alive, version: ’ + response.version + ', response: ’ + response.kinvey);
var activeUser = Kinvey.User.getActiveUser();
if (activeUser == null) {
var promise = Kinvey.User.login(‘root’, ‘root’)
.then(function (user) {
console.log(“login successfull…”);
})
.catch(function (error) {
console.log(error);
});
}
})
.catch(function (error) {
console.log('Kinvey Ping Failed. Response: ’ + error.description);
});
})
.catch(function (error) {
console.log(error);
});

application.start({ moduleName: “home/home-page” });

home-page.xml

<ActionBar title="Home" class="action-bar">
</ActionBar>
<GridLayout rows="auto,*">

<Button text="tap to load list" tap="{{ onButtonTap }}" row="0" />
	<lv:RadListView items="{{ contactList }}" row="1">

		<lv:RadListView.itemTemplate>
			<GridLayout rows="*" columns="50,*" borderWidth=".01">
		
				<GridLayout rows="*,*,*,*" columns="*" row='0' colSpan='2'>
					<Label text="{{title+firstname+'\t'+lastname}}" row='0' fontWeight="bold" textAlignment="center" />
					<Label text="{{shopname +', '+ phone}}" row='1' textAlignment="center" />
					<Label text="{{adl1+', '+adl2 }}" row='2' textAlignment="center" />
					<Label text="{{city +', '+state }}" row='3' textAlignment="center" />
				</GridLayout>
			</GridLayout>

		</lv:RadListView.itemTemplate>

	</lv:RadListView>
	

</GridLayout>

home-page.js

var frameModule = require(“ui/frame”);
var HomeViewModel = require("./home-view-model");
var homeViewModel = new HomeViewModel();
function pageLoaded(args) {
var page = args.object;
page.bindingContext = homeViewModel;
}
exports.pageLoaded = pageLoaded;

home-view-model.js

var observableModule = require(“data/observable”);
var frameModule = require(“ui/frame”); // frame module to navigate to different page
var Kinvey = require(‘kinvey-nativescript-sdk’).Kinvey;

function HomeViewModel() {

var viewModel = observableModule.fromObject({

contactList: "",
onButtonTap: function () {
  console.log("Button was pressed");
  var dataStore = Kinvey.DataStore.collection('contacts');
  const subscription = dataStore.find()
    .subscribe(function (entities) {

      console.log(entities);
      //console.log(entities.firstname); // output is undefined

      viewModel.set("contactList", entities);
    }, function (error) {
      console.log(error);
    }, function () {
    });
},

});

return viewModel;
}

module.exports = HomeViewModel;


#6

no answer for my post from anyone…


#7

I will be able to take a look if you could setup the Playground.


#8

this problem is very important so i setup the problem code on playground .

click below:

or login to playground using:

email: nativescript@gmx.com
password: native@123


#9
  1. It always returns array of entities (not object).
  2. Do not relay on next callback, use the complete callback of subscribe (third argument function). Next function (first argument function) is immediately called with local cache then called once again with updated data from server. At first launch local cache will be empty, so you get empty array on first callback and with values from second callback.

#10

seriously i didnt get you. i just want to print one data from entity that is firstname,
wheather it is possible or not please tell me…even in kinvey documnet they have mentioned it is not possible to read single data from a row… so im not getting a way to use this entity coz based on one data from an entity i need to put if condition to do some validation…


#11

To keep the answer simple for you, consider it’s always an array. You can do something like this,

 var dataStore = Kinvey.DataStore.collection('contacts');
      const subscription = dataStore.find()
        .subscribe(function (entities) {

          console.log(entities);
          if(entities.length){
             console.log('------------------' + "entities[0].firstname  : " + entities[0].firstname + "--------------------");
          }
             viewModel.set("contactList", entities);
          
        }, function (error) {
          console.log(error);
        }, function () {
        });

#12

console.log(entities[0].firstname );

output:

TypeError: Cannot read property ‘firstname’ of undefined


#13

Please use the exact code I had written in previous post, check the length before you access it. If it still doesn’t work share the updated playground example.


#14

thak you very much the problem resolved… but 1 simple doubt ??
why without if condition i.e entity.length the code not work ???

and i want to print all contact’s first name for that i tried like
entities[2].firstname and entities.firstname it didnt worked so i choose for loop to do that .

anyhow thank you problem got somewhat resolved…


#15

I have already explained why - initially the array will be empty, later when callback is hit the second time it will have values.